diff --git a/src/cdk/text-field/_text-field.scss b/src/cdk/text-field/_text-field.scss index f7d1bd8a04e..82ecffcf480 100644 --- a/src/cdk/text-field/_text-field.scss +++ b/src/cdk/text-field/_text-field.scss @@ -19,6 +19,18 @@ textarea.cdk-textarea-autosize { resize: none; } + + // This class is temporarily applied to the textarea when it is being measured. It is immediately + // removed when measuring is complete. We use `!important` rules here to make sure user-specified + // rules do not interfere with the measurement. + textarea.cdk-textarea-autosize-measuring { + height: auto !important; + overflow: hidden !important; + // Having 2px top and bottom padding seems to fix a bug where Chrome gets an incorrect + // measurement. We just have to account for it later and subtract it off the final result. + padding: 2px 0 !important; + box-sizing: content-box !important; + } } // Used to generate UIDs for keyframes used to change the text field autofill styles. diff --git a/src/cdk/text-field/autosize.ts b/src/cdk/text-field/autosize.ts index 568b0c1d61f..9f9bb437126 100644 --- a/src/cdk/text-field/autosize.ts +++ b/src/cdk/text-field/autosize.ts @@ -187,15 +187,16 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { // Long placeholders that are wider than the textarea width may lead to a bigger scrollHeight // value. To ensure that the scrollHeight is not bigger than the content, the placeholders // need to be removed temporarily. - textarea.style.height = 'auto'; - textarea.style.overflow = 'hidden'; + textarea.classList.add('cdk-textarea-autosize-measuring'); textarea.placeholder = ''; - const height = textarea.scrollHeight; + // The cdk-textarea-autosize-measuring class includes a 2px padding to workaround an issue with + // Chrome, so we account for that extra space here by subtracting 4 (2px top + 2px bottom). + const height = textarea.scrollHeight - 4; // Use the scrollHeight to know how large the textarea *would* be if fit its entire value. textarea.style.height = `${height}px`; - textarea.style.overflow = ''; + textarea.classList.remove('cdk-textarea-autosize-measuring'); textarea.placeholder = placeholderText; // On Firefox resizing the textarea will prevent it from scrolling to the caret position. diff --git a/src/lib/input/input.scss b/src/lib/input/input.scss index 9827e3b9c86..7ee4bba6362 100644 --- a/src/lib/input/input.scss +++ b/src/lib/input/input.scss @@ -92,3 +92,10 @@ textarea.mat-input-element { resize: none; } } + +textarea.mat-input-element { + // The 2px padding prevents scrollbars from appearing on Chrome even when they aren't needed. + // We also add a negative margin to negate the effect of the padding on the layout. + padding: 2px 0; + margin: -2px 0; +}