angular/components

bug(form-field): mat-label disappears when density < -1

Opened this issue ยท 14 comments

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

Hi,
There seems to be an issue where the mat-labels disappear when the density of form-field is set to lower than -1. I don't think this is as designed...

Reproduction

Steps to reproduce:

  1. Set the density option to anything lower than -1, ex: @include mat.form-field-density(-2);
  2. Include a mat-form-field with the appearance set to "fill", with a mat-label

notice the labels do not appear. (Their css is set as "display:none;")

Demo: https://stackblitz.com/edit/angular-wvlwej
In the stackblitz, you can see that the labels appear fine when density is set at >= -1, but anything lower and the label is hidden.

image

Expected Behavior

The labels should be visible

Actual Behavior

The labels are not visible

Environment

  • Angular: 15.1.3
  • CDK/Material: 15.1.3
  • Browser(s): Chrome Version 109.0.5414.120
  • Operating System (e.g. Windows, macOS, Ubuntu): Windows

Adding more information:

As mentioned by @eLarocque, the issue only happens to mat-form-field with appearance="fill", it does not happen for appearance="outline". The following image is for density: -2:

image

You can check this issue in this URL: https://angular-material-density.netlify.app/
Source code: https://github.com/CrlsMrls/angular-material-component-densities

Environment

Angular: 15.1.4
CDK/Material: 15.1.4
Browser(s): Chrome Version 110.0.5481.77 (Official Build) (arm64) and Safari Version 16.2
Operating System: macOS

Nobody cares about this bug it seems ๐Ÿ˜„ very annoying when you need to customize the large application.

Any plans to fix it?

From dev comments:
"MDC hides the label in their density styles when the height decreases too much."
Ok, but why is the placeholder disappearing too?? So FormField with density < -1 is completely non-working and can't be used in production.

With the density support in Material v15, I was hoping to be able to make my forms a lot denser. Unfortunately, the result after the upgrade is that my forms are now even sparser.

The default size of the input box has grown in v15 (with the default density 0) compared to v14. In order to restore my forms back to their original size, I must use density -3 as this image illustrates:
image
Therefore, I really would like this issue to be resolved since an input box without a label is useless in our application.

After that, I would like to be able to actually make the forms denser with labels remaining. But setting density to e.g. -4 or -5 results in compile errors. What am I missing, wasn't the main idea of density from the beginning to make components denser/smaller than in v14 for large applications with many input fields?

With the density support in Material v15, I was hoping to be able to make my forms a lot denser. Unfortunately, the result after the upgrade is that my forms are now even sparser.

The default size of the input box has grown in v15 (with the default density 0) compared to v14. In order to restore my forms back to their original size, I must use density -3 as this image illustrates: image Therefore, I really would like this issue to be resolved since an input box without a label is useless in our application.

After that, I would like to be able to actually make the forms denser with labels remaining. But setting density to e.g. -4 or -5 results in compile errors. What am I missing, wasn't the main idea of density from the beginning to make components denser/smaller than in v14 for large applications with many input fields?

I have compile errors with -5, but "minimum" works.
@include mat.form-field-density(minimum);
it equals to
@include mat.form-field-density(-5);

There are a couple of hacks. In styles.scss before the imports add @use '@material/textfield';
After the imports, before the includes add textfield.$minimum-height-for-filled-label: 10px;. That will override the minimum height for a label.

Or you can add a global style .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) .mat-mdc-floating-label { display: inline; }

This deserves more attention from the angular team because migrating to v15 increases the input sizes so much that we would need to set the density to -3 (or even deeper) level.

Do we have a solution for this?

JoukeD commented

The solution proposed by @NachmanBerkowitz worked for me, by adding @use '@material/textfield'; to the top of the style.scss and then adding:

// show label for more dense inputs as well
.mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined)
  .mat-mdc-floating-label {
  display: inline !important;
}

When not setting the mat.private-form-field-density lower then -2 this still looks ok and input text and label don't overlap.

@JoukeD, I guess you would agree the solution you proposed is just a temporal fix and the angular team should still fix the issue.

@material/textfield has been removed from @angular/material since 18.1.2
Which breaks the workaround using

@use '@material/textfield';
textfield.$minimum-height-for-filled-label: 10px;

Any other options?

.mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined)
  .mat-mdc-floating-label {
  display: inline !important;
}

Does not seem to have the same effect.

UPDATE:
This seems to fix it in my case (used it with form-field-density(-4))

:root {
  --mat-form-field-filled-label-display: block;
  --mat-form-field-filled-with-label-container-padding-top: 16px;
  --mat-form-field-filled-with-label-container-padding-bottom: 0px;
}

Thank you, OP, for highlighting the exact issue I'm facing. I initially thought I might have done something wrong, but it turns out the Angular team has hidden the label unexpectedly. It's been two years, and still no solution provided. A label is such a basic form element; it really shouldnโ€™t just disappear like this!

The CSS vars above left the label too close to the top for me. I had to adjust the transform on it.

.mdc-floating-label--float-above {
transform: translateY(-90%) scale(.60); //was -106% and 0.75
}