-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Unresolvable dependencies in determining the rendered fieldset legend #2756
Comments
http://software.hixie.ch/utilities/js/live-dom-viewer/saved/5243 suggests Gecko doesn't force display:block. @bzbarsky do you know how this is done in Gecko? |
So just so we're clear, the "overriding the display value" means overriding used display. Computed display is unaffected. This means the determination does not in fact need to be made until you're creating the box or otherwise need the used display value. The exact check Gecko does to determine whether a legend is a rendered legend is that all of the following conditions have to hold:
This is not the same as checking whether the box is positioned or floated; as you note that is a much more complicated check and has chicken-and-egg problems. But it is equivalent in common cases. And in some cases (e.g. a |
Thank you! Checking computed value seems sane to me. I don't like checking parent box rather than DOM parent. @mstensho would this approach work better in chromium? |
What is the interaction with
What Gecko does is that the first testcase has the legend be the rendered legend; the second and third show that Gecko does not support Chrome with --enable-experimental-web-platform-feature doesn't support What is the interaction with shadow DOM? |
Using computed style as an approximation to actual layout should be easy enough, but as @bzbarsky points out, it's not guaranteed to be the same, although it will in common cases. But I suppose the spec needs to explain this somehow. Another funny complication of letting the renderedness of a legend affect box type, is that changing style on one LEGEND (or inserting or removing the node from the DOM, for that matter) node dynamically may affect some sibling (that will suddenly cease to be, or become, the rendered legend):
Here, #second is the rendered legend, so it's block-displayed. Now, if we change the display property of #first to "block" (or "inline" or "table" or whatever, except perhaps "contents"), #first will become the rendered legend, which means that #second will change to a regular box, and no longer be the rendered legend. In other words, the box is changed from "block" to "inline". Nothing wrong with that, just funny/complicated. |
That's an interesting point. As far as I can tell, Gecko gives any non-floated non-abs/fixedpos legend that's a child of a fieldset a block-inside box. Depending on whether the original display was block-level or inline-level it basically acts like a block or inline-block. This is not restricted to just the "rendered legend". So I guess Gecko actually has two concepts: an "in-flow legend in a fieldset", which gets special box handling, and "rendered legend", which is the first "in-flow legend in a fieldset" for a given fiedset. What do other UAs do? |
Blink: All LEGEND elements that aren't display:none are forced to display:block. The rendered legend is determined after box creation: The first child box that is a LEGEND element and isn't out of flow becomes the rendered legend. All LEGEND elements also establish a block formatting context and they all shrink to fit, but I'm going to change that: https://chromium-review.googlesource.com/c/535595/ There's no mechanism to properly re-layout the boxes if we change which of the LEGENDs is the rendered one. E.g.
#first is the rendered legend, but if we change it to display:none, #second becomes the rendered legend. But Blink has no mechanism to detect that this requires re-layout of #second, so it won't shrink to fit (until you somehow trigger layout of it via other means, such as resizing the window). |
Hmm. That's also the case in Gecko, for all legend whose parent box is a fieldset. What do other UAs do? It really would be good to sort out what spec we can all agree on before currently-compatible-across-UAs behavior gets changed in some UAs. |
I'd really like to land this change in Blink rather sooner than later, because this is a regression fix, sort of. Previously, no LEGEND established a block formatting context, but they all rather had this non-standard "avoid floats on the outside, but don't contain descendant floats" thing, which I removed some weeks ago, and turned them all into proper BFCs instead. And then I realized that this change made non-rendered legends more magical than before, in a sense. |
I would be OK with having a concept of "potential rendered legend", which is any legend that is a child of a fieldset (DOM child, possibly flat tree child if there's a use case for that). A potential rendered legend would always be a BFC and shrink-wrap, maybe even force display:block (if not display:none or display:contents). Per https://drafts.csswg.org/css-display/#unbox-html , CSS WG consensus is that display:contents should work on fieldset and legend. I think it would be nice to have it work, and there's at least a recent tweet wishing for the same. So how about display:contents on fieldset means it can't have any potential rendered legend, and a legend with |
Ah. Again, what is the behavior in other UAs?
Again, what is the expected rendering of:
and why? |
The outer fieldset renders as a normal fieldset (without a legend); the inner fieldset honors display:contents, and the legend is a normal block (because "display:contents on fieldset means it can't have any potential rendered legend"). I can work on a pull request and tests to make things clearer. I'll also check WebKit and EdgeHTML. |
Per comments in #3331 it appears that this is implemented differently to what I suggested would happen above. In particular, the with example above, the outer fieldset has the legend as its rendered legend in WebKit/Chromium/Gecko. (EdgeHTML 17 doesn't support |
Properly define the rendering of the fieldset and legend elements. The layout model used is most similar to Gecko, which uses an anonymous box to hold the fieldset's contents. Fixes #3955, fixes #3930, fixes #3929, fixes #3928, fixes #3927, fixes #3915, fixes #3913, fixes #3660, fixes #3331, fixes #2756, fixes #4013. Tests: https://github.com/web-platform-tests/wpt/tree/master/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements https://github.com/web-platform-tests/wpt/tree/master/html/semantics/forms/the-fieldset-element
Properly define the rendering of the fieldset and legend elements. The layout model used is most similar to Gecko, which uses an anonymous box to hold the fieldset's contents. Fixes whatwg#3955, fixes whatwg#3930, fixes whatwg#3929, fixes whatwg#3928, fixes whatwg#3927, fixes whatwg#3915, fixes whatwg#3913, fixes whatwg#3660, fixes whatwg#3331, fixes whatwg#2756, fixes whatwg#4013. Tests: https://github.com/web-platform-tests/wpt/tree/master/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements https://github.com/web-platform-tests/wpt/tree/master/html/semantics/forms/the-fieldset-element
Properly define the rendering of the fieldset and legend elements. The layout model used is most similar to Gecko, which uses an anonymous box to hold the fieldset's contents. Fixes whatwg#3955, fixes whatwg#3930, fixes whatwg#3929, fixes whatwg#3928, fixes whatwg#3927, fixes whatwg#3915, fixes whatwg#3913, fixes whatwg#3660, fixes whatwg#3331, fixes whatwg#2756, fixes whatwg#4013. Tests: https://github.com/web-platform-tests/wpt/tree/master/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements https://github.com/web-platform-tests/wpt/tree/master/html/semantics/forms/the-fieldset-element
https://html.spec.whatwg.org/multipage/rendering.html#rendered-legend
The spec says that a fieldset element's rendered legend is to be rendered over the block-start border edge of the fieldset element as a block box, overriding any explicit 'display' value.
How to determine whether it's a rendered legend? The spec says that, among other things, we need to make sure that a candidate LEGEND element is not out-of-flow (e.g. not absolutely positioned or floated).
This is typically not something you want to figure out without creating the layout box for it first, is it?
So, we first need to figure out if a LEGEND is in-flow before we determine whether to override 'display' to 'block'. We need to resolve the actual display type before creating the box, but in order to do that, we need to know that the box is going to be a rendered legend, i.e. it has to be in-flow, among other things. But we don't have the box yet, because we don't know what type of box to create, because first we need to know if it's going to become a rendered legend. Chicken, meet egg. :)
Okay, it could indeed be possible to walk the flat DOM tree and make highly qualified guesses as to whether an element would generate an in-flow box or not, but it really doesn't sound that tempting.
The only solution i can think of, is to force all LEGEND elements (that don't have display:none or display:contents) to become display:block.
Then again: I'm an Blink layout engine implementor. Could this be something that's only awkward to do in Blink / WebKit?
The text was updated successfully, but these errors were encountered: