Is this a regression?
The previous version in which this bug was not present was
14.x (verified on v14.material.angular.dev, Angular 14.0.0)
Description
When cdkTextareaAutosize is used on a matInput textarea inside mat-form-field, the cached line height used for cdkAutosizeMinRows / cdkAutosizeMaxRows is measured with the browser's default textarea font instead of the form field's font. As a result, min-height / max-height are too small until the window is resized.
Cause (as far as I can tell):
CdkTextareaAutosize measures and caches the line height on the first ngDoCheck (resizeToFitContent → _cacheTextareaLineHeight, cloning the textarea with rows=1).
MatInput applies font: inherit via the class mat-mdc-form-field-input-control, which is a dynamic host binding ('[class.mat-mdc-form-field-input-control]': '_isInFormField').
- Host bindings are applied after
ngDoCheck in the first change detection pass. So at measuring time the textarea (and its clone) still uses the UA default textarea font (Chrome: monospace 13.33px, line-height: normal ≈ 15px).
- The wrong value stays cached until a window
resize clears it.
Measured on the official docs example (cdkAutosizeMaxRows="5", actual line height 24px):
| Docs |
Angular |
measured line height |
max-height |
| v14 |
14.0.0 |
18px (correct) |
90px |
| v15 |
15.1.1 |
15px |
75px |
| v17 |
17.3.0 |
15px |
75px |
| v19 |
19.2.6 |
15px |
75px |
| v21 |
21.2.11 |
15px |
75px |
| current |
22.2.1 |
15px |
75px (expected 120px) |
It started with v15, i.e. the switch to the MDC-based form field.
Workaround: a global style so the textarea inherits the font before the first measurement:
textarea.cdk-textarea-autosize { font: inherit; letter-spacing: inherit; }
Reproduction
No StackBlitz needed – the official docs example reproduces it:
https://material.angular.dev/cdk/text-field/examples ("Auto-resizing textarea")
Steps to reproduce:
- Open the page above (fresh load, don't resize the window).
- Select the textarea in DevTools and run:
({ minHeight: $0.style.minHeight, maxHeight: $0.style.maxHeight, lineHeight: getComputedStyle($0).lineHeight })
→ minHeight: "15px", maxHeight: "75px", lineHeight: "24px"
- Type more than 3 lines: the textarea starts scrolling after ~3 lines instead of 5.
- Resize the browser window and run the snippet again →
minHeight: "24px", maxHeight: "120px" (correct).
For comparison, the same example on https://v14.material.angular.dev/cdk/text-field/examples measures correctly on first load.
Expected Behavior
min-height / max-height are based on the actual line height of the textarea (24px → max-height: 120px for 5 rows) right after the first render.
Actual Behavior
They are based on the UA default textarea font (15px → max-height: 75px) until the window is resized.
Environment
- Angular 22.2.1
- CDK/Material 22.2.x
- Chrome (Version 154.0.8037.95 (64-Bit))
- Windows 11
Is this a regression?
The previous version in which this bug was not present was
14.x (verified on v14.material.angular.dev, Angular 14.0.0)
Description
When
cdkTextareaAutosizeis used on amatInputtextarea insidemat-form-field, the cached line height used forcdkAutosizeMinRows/cdkAutosizeMaxRowsis measured with the browser's default textarea font instead of the form field's font. As a result,min-height/max-heightare too small until the window is resized.Cause (as far as I can tell):
CdkTextareaAutosizemeasures and caches the line height on the firstngDoCheck(resizeToFitContent→_cacheTextareaLineHeight, cloning the textarea withrows=1).MatInputappliesfont: inheritvia the classmat-mdc-form-field-input-control, which is a dynamic host binding ('[class.mat-mdc-form-field-input-control]': '_isInFormField').ngDoCheckin the first change detection pass. So at measuring time the textarea (and its clone) still uses the UA default textarea font (Chrome: monospace 13.33px,line-height: normal≈ 15px).resizeclears it.Measured on the official docs example (
cdkAutosizeMaxRows="5", actual line height 24px):max-heightIt started with v15, i.e. the switch to the MDC-based form field.
Workaround: a global style so the textarea inherits the font before the first measurement:
Reproduction
No StackBlitz needed – the official docs example reproduces it:
https://material.angular.dev/cdk/text-field/examples ("Auto-resizing textarea")
Steps to reproduce:
minHeight: "15px",maxHeight: "75px",lineHeight: "24px"minHeight: "24px",maxHeight: "120px"(correct).For comparison, the same example on https://v14.material.angular.dev/cdk/text-field/examples measures correctly on first load.
Expected Behavior
min-height / max-height are based on the actual line height of the textarea (24px → max-height: 120px for 5 rows) right after the first render.
Actual Behavior
They are based on the UA default textarea font (15px → max-height: 75px) until the window is resized.
Environment