Skip to content

fix(form-field): scrollbars appear on autosize textarea in chrome #10811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/cdk/text-field/_text-field.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 5 additions & 4 deletions src/cdk/text-field/autosize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions src/lib/input/input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}