Child element height incorrect when it is a descendent of a display:flex container
Reported by
mi...@styra.com,
Feb 24 2017
|
||||||
Issue description
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Steps to reproduce the problem:
Background:
* I am using react-mdl as a UI library.
* I am wrapping the react-mdl Textfield component in order to resize a textarea’s height based on its content.
* The code for resizing the textarea is effectively (I have simplified it somewhat and annotated it for the sake of an example):
function caluclateRows(textarea) {
// 1. Set textarea’s height equal to line-height (i.e., 1 row or 20px) so that
// scrollHeight represents the height of its contents (as opposed to a perhaps
// empty height based on the current value of its rows attribute).
textarea.style.height = '20px';
// 2. Calculate an even number of rows based on the line-height (20),
// textarea’s scrollHeight, and a maximum number of rows (5).
var scrollHeight = textarea.scrollHeight;
var rows = Math.min((scrollHeight - scrollHeight % 20) / 20, 5);
// 3. Reset textarea’s height so that it sizes itself based on the value of
// its rows attribute.
textarea.style.height = 'auto';
// 4. Return the number of rows (minimum of 1, maximum of 5), which will be
// used to set textarea’s rows attribute in JSX. For example:
//
// <Textfield ref={(x) => this.input = x} rows={caluclateRows(this.input)}/>
return rows;
}
What is the expected behavior?
In this example, textarea is a sibling of another element – label – which is positioned relative to a common parent. label should grow and shrink in direct proportion to textarea because the parent grows and shrinks accordingly.
This always works as expected in Safari and Firefox.
This works as expected in Chrome unless textarea and label are descendents of a display:flex container.
What went wrong?
You can see in the first attachment that the the blue focus line (an absolutely positioned :after pseudo-element of label) isn’t positioned correctly as the textarea grows and shrinks. This is because label’s height does not change as expected. This is caused by label’s great-great-grandparent element: div.s3a-ui--dialog--row-content, which is display:flex.
Did this work before? N/A
Does this work in other browsers? Yes
Chrome version: 56.0.2924.87 Channel: stable
OS Version: OS X 10.11.6
Flash Version:
In the second attachment, you can see that the blue focus line is positioned as expected because label’s height is changing correctly. Either we don’t use display:flex with the container or we can work around the issue by poking label’s height style:
function caluclateRowsWorkaround(textarea) {
// 1. Get a reference to the label element, which is absolutely positioned
// relative to its parent.
var label = textarea.parentElement.querySelector('.mdl-textfield__label');
// 2. Set textarea’s height equal to line-height (i.e., 1 row or 20px) so that
// scrollHeight represents the height of its contents (as opposed to a perhaps
// empty height based on the current value of its rows attribute).
textarea.style.height = '20px';
// 3. Change the way that label calculates its height, which should happen
// automatically based on its top and bottom position relative to its parent,
// but does not.
label.style.height = '100%';
// 4. Calculate an even number of rows based on the line-height (20),
// textarea’s scrollHeight, and a maximum number of rows (5).
var scrollHeight = textarea.scrollHeight;
var rows = Math.min((scrollHeight - scrollHeight % 20) / 20, 5);
// 5. Reset textarea’s height so that it sizes itself based on the value of
// its rows attribute.
textarea.style.height = 'auto';
// 6. Reset label’s height so that it sizes itself based on its top and bottom
// CSS values relative to its parent as it is supposed to.
label.style.height = 'auto';
// 7. Return the number of rows (minimum of 1, maximum of 5), which will be
// used to set textarea’s rows attribute in JSX. For example:
//
// <Textfield ref={(x) => this.input = x} rows={caluclateRows(this.input)}/>
return rows;
}
,
Feb 27 2017
Reporter@ - Thanks for filing the issue...!! Could you please provide a sample html file to test this issue. This will help us in triaging the issue further. Thanks...!!
,
Feb 27 2017
Here you go...
,
Feb 27 2017
I can reproduce this on Chrome 56 Mac by entering text with newlines (shift-enter): http://output.jsbin.com/sikiroq Seems to work fine in Chrome 57 (checked both MacOS and ChromeOS), so presumably already fixed. cbiesinger@ worth getting a bisect to confirm this was fixed intentionally with appropriate tests added?
,
Mar 1 2017
Thanks for providing feedback. Removing "Needs-Feedback" label.
,
Mar 1 2017
Able to reproduce the issue on Mac 10.12.2, Win-10 and Ubuntu 14.04 using chrome reported version #56.0.2924.87 but the same is not reproducible in the latest canary #58.0.3026.0. Reverse Bisect Information: ===================== Good build: 57.0.2943.0 Revision(436483) Bad Build : 57.0.2942.0 Revision(436203) Change Log URL: https://chromium.googlesource.com/chromium/src/+log/915e461af0dcb90d0d98b1aab614f409d8770379..9d96126f67850daf3c07586dc09fa334d592529c From the above change log suspecting below change Review url: https://codereview.chromium.org/2553833002 mstensho@ - Could you please check and merge the fix to M-57 if it is a valid candidate. Thanks...!!
,
Mar 1 2017
We shouldn't merge that CL. Too risky. It would require us to merge a bunch of other preceding CLs. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by nyerramilli@chromium.org
, Feb 27 2017