bug(form-field): label-offset-x is incorrectly computed when there is a prefix
- Dominant language
- TypeScript
- Stars
- 25k
- Forks
- 6.8k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 91
Description
### 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
Inside `_mdc-text-field-structure-overrides.scss`
https://github.com/angular/components/blob/7bb0a82a434c40d01a0d1aa35bcddaa3f725eccb/src/material/form-field/_mdc-text-field-structure-overrides.scss#L97
We can see that the variable `--mat-mdc-form-field-label-offset-x` is hardcoded to -16px (I guess it's coming from the fact that out of the box, form-field have a left-padding of 16px).
But for outlined form field, the left-padding could get bigger in some cases when using a large value for the border-radius.
This is because the left-padding is defined with `max(16px, var(--mdc-outlined-text-field-container-shape) + 4px)`
So if I want my outlined form-fields to be rounded like a pill, I have to override the border-radius with this
```
@include mat.form-field-overrides((
outlined-container-shape: 28px,
))
```
Which will set the left-padding to 32px and not 16px.
At this point everything looks good, and the label is correctly placed (when empty, it's aligned with the input value/placeholder)
But things start to break when you add a prefix as it will `translateX` the label to make room for the prefix.
This transform is based on the hardcoded value of `--mat-mdc-form-field-label-offset-x: -16px;`, so it works great for out-of-the-box form-field, but doesn't work for my pill form-field.
Because the padding is set to 32px, the `--mat-mdc-form-field-label-offset-x` should be -32px and not -16px.
So I end up with this:
As you can see, the empty pill form-field's label isn't aligned anymore with where the input's value is.
I know this can be fixed by overriding the `--mat-mdc-form-field-label-offset-x` myself by using `::ng-deep` to override the hardcoded value, but it's not something trivial to understand and fix, so I'd rather see a fix in the Angular Material repository.
### Reproduction
https://stackblitz.com/edit/tk7fhpq7-w7dz4vdj?file=src%2Fexample%2Fform-field.scss
### Expected Behavior
The label should be correctly placed when using a large border-radius value for outlined form-field, like the input value is.
I believe the solution would be to change this line of code:
```diff
- --mat-mdc-form-field-label-offset-x: -16px;
+ --mat-mdc-form-field-label-offset-x: max(16px, var(--mdc-outlined-text-field-container-shape, var(--mat-sys-corner-extra-small)) + 4px) * -1;
```
By the way, it would be nice to be able to control the "minimum" left & right padding to something else than the hardcoded 16px too 😅
### Actual Behavior
The label is not correctly aligned.
### Environment
- Angular: 20.0.4
- CDK/Material: 20.0.4
- Browser(s): Chrome 137
- Operating System: macOS
Contributor guide
Research direction
Start in src/material/form-field/_mdc-text-field-structure-overrides.scss at the label-offset-x declaration described in the issue, then use the linked StackBlitz reproduction with an outlined field, large container shape, and prefix. Verify the label alignment against the input value for the empty field; done means the label remains correctly aligned in that configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, scss
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100