serenity icon indicating copy to clipboard operation
serenity copied to clipboard

LibWeb: Material UI full-width input field has its label missing

Open FalseHonesty opened this issue 2 years ago • 1 comments

Material UI's fullWidth input field isn't displaying the label text correctly.

Chrome: image

Ladybird: image

Here is a trimmed & static reproducible example where the fullWidth text shows in Chrome, but not Ladybird:

<!DOCTYPE html><style>
.outer {
    display: flex;
}

.middle {
    width: 500px;
}

.inner {
    position: relative;
    width: 100%;
}

label {
    position: absolute;
    overflow: hidden;
    max-width: 100%;
}
</style>
<body><div class="outer"><div class="middle"><div class="inner"><label>fullWidth</label>

The reason the label is gone is because the width of label has been determined to be 0px, and overflow: hidden is trimming it all away. I've tried getting to the bottom of this issue, but I've struggled to wrap my brain around how the FFC is participating. As far as I can tell, the following steps are leading to the issue:

  1. .outer lays out .middle, and calculates min/max content sizes using calculate_{min,max}_content_width
  2. calculate_{min,max}_content_width sets .middle's width to be indefinite.
  3. Since .middle's width is (temporarily) indefinite, .inner's width isn't set to 500px like it is if .outer is a BFC.
  4. .inner's width is calculated to be 0px
  5. label is laid out using .inner as its containing box (due to the position styles I think), which has a width of 0px.
  6. Since label's containing block is 0px, the max-width style trims its width to also be 0px.
  7. label decides its width is now "definite" at 0px
  8. A later pass (perhaps by the FFC) re-calculates .inner's width to be 500px.
  9. label is re-laid out, but since its width has already been determined to be "definite", it does not re-calculate using the new max-width.

IF the above steps are accurate, I'm also struggling to understand what the correct solution here is. Should the width of .inner never be calculated to be 0px (step 4)? Should label always re-calculate width (step 9)?

FalseHonesty avatar Oct 31 '23 01:10 FalseHonesty

After further investigation, it looks like the initial layout of the label element (where the percentage resolves incorrectly) is spec accurate:

For the purpose of calculating an intrinsic size of the box (e.g. the box’s min-content size), a content-based minimum size causes the box’s size in that axis to become indefinite (even if e.g. its width property specifies a definite size). Note this means that percentages calculated against this size will behave as auto.

But the follow-up paragraph says that we should still correctly resolve percentages using an additional layout pass

Nonetheless, although this may require an additional layout pass to re-resolve percentages in some cases, this value (like the min-content, max-content, and fit-content values defined in [CSS-SIZING-3]) does not prevent the resolution of percentage sizes within the item.

This leads me to believe that in the final layout pass, we should be fully re-calculating the element's width with the correctly resolving percentages, but I still haven't figured out how to do that yet 😅

FalseHonesty avatar Nov 04 '23 01:11 FalseHonesty