-
Notifications
You must be signed in to change notification settings - Fork 707
[css-display] Define interaction of display:contents and replaced elements #540
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
Comments
We ignore So I think this change is basically wrong: |
The CSSWG decided to treat |
LGTM |
I fully agree with bz in #1024 (comment) The spec should say that In general, adding new spec language that makes a computed value depend on layout stuff such as box construction is pretty much always bad. |
WG discussed this today. Problem with making it "behaves as" is that there are plenty of other properties that care about the box that the element will generate; it's generally very significant whether something generates an inline, block, or no box at all. So we can't just push this to used-value with the "behaves as" language; this is fundamentally a computed-value issue. So impls either need to bite the bullet and allow this computed value to depend on form-control-ness (as, according to François, Firefox already does?), or shoot for a simpler resolution, like making |
While I see your point, knowing both Blink's and Gecko's implementation, this is sort of complex to implement at computed value time. All the logic to decide whether an element generates a box resides on the actual box construction step, probably with This will mean having to keep track of whether an element generates a box when its specified value is How painful or difficult those changes are I don't know ahead of time, tbh.
Firefox doesn't. For a quick example, the following logs <!doctype html>
<button style="display: contents">Foo</button>
<script>
console.log(getComputedStyle(document.querySelector('button')).display)
</script>
This is definitely simpler to implement, though I'm not sure all the people would be on board with this. @MatsPalmgren or @rune-opera may have opinions here? |
(Also please note that ATM I'm not an official voice from neither Blink or Gecko, I just happen to know a bit about how this is implemented in them) |
After a bit more thought, maybe even the |
My comment on the call was that we had chosen I didn't check what the getComputedStyle function returned, but to be fair -- in Edge at least -- this function could return you any value independently of what we actually store in our formats, I don't think that is particularly relevant. If Gecko desires to store formats in one way that is not what a spec says the computed value is, it should be perfectly fine as long as there is some code in getComputedStyle that takes care of returning the expected value to authors, and they have function in their codebase like In Edge, getting a value through getComputedStyle will regularly trigger some new cascade pass for the asked property if the value stored in the formats isn't enough to synthetize the value to return. This is desirable also to prevent :visited styles from leaking out for properties that might be affected by that. In short, I am not entirely sure why there is so much push from gecko to "dumbify" the computed value of properties to the point they end up being the specified value in almost all the cases. The computed value is a concept, and is not tied to your implementation of formatting in any strong way. |
@tabatkins I'm not entirely sure that's the best summary. Afaict the conclusion was that it's a more complicated issue than expected and people needed more time to contemplate. It's on the agenda again for next week. Minutes are here: https://lists.w3.org/Archives/Public/www-style/2017Feb/0088.html @FremyCompany At least one concern in Firefox is caching of computed values through inheritance or defaulting. There's more discussion about it in various old Flexbox threads on www-style. |
The reason that the concept of computed value is important is that the computed value concept is what inheritance operates on. Inheritance happens as part of style computation. Software architecture depends on being able to split software into pieces in useful ways. Being able to separate parts of software allows both maintainability and the ability to make the pieces happen at different times. While the divisions in different engines are somewhat different from each other, many performance optimizations that the Web depends on depend on separation between different parts of a software system in various ways. Currently style computation is tied to the differences between elements only (I think) via the UA stylesheet and via the rules for mapping presentational attributes into CSS, which are both forms of specified values that are the normal input to the style computation process. Likewise, style computation is separate from selector matching (which happens before it) and from box construction (which happens after it), which is in turn separate from intrinsic size calculation, which is separate from layout calculation, which is separate from painting and compositing. Currently CSS computed values are a function of specified values (which include the UA style sheet, and are based on the results of selector matching), which pseudo-element the values are for (considering a regular element as a single type), and the computed values of the parent (i.e., what the element inherits from) and occasionally the grandparent. We've designed large amounts of software around those assumptions. While we might be willing to the substantial amounts of work to stop depending on these assumptions for a good reason, I don't want to change them for handling of an edge case that wasn't one of the actual use cases for which the feature was designed and implemented (and wasn't brought up until a year or so later). I'd also like to point out that there's a third option: that for replaced elements, display:contents just removes the replaced-ness of the element and allows the children to display as though the replaced element weren't there. (The previous two options were treating as none, and treating as inline.) I think there's a decent argument that this might even be the most logical option. |
The difficulty with my option 3 is that it's not necessarily clear what aspects of form controls are associated with their box and what aspects are associated with their DOM node. So it seems likely to lead to non-interoperability in terms of what aspects of the form-control-ness go away. |
The group just discussed this, and ended up inclined towards display:none rather than trying to go through making display:contents show the children, for replaced elements and form controls. In response to @emilio's #540 (comment) -- I don't quite follow the concerns, although it's not clear to me that the concern would be worse with one approach than the other (rather than the old display:inline, which has other serious problems). Though if you still think this is problematic, I'd be interested to understand better why it is. |
@bzbarsky raised the issue of what to do with Options are:
See minutes from the currently-active resolution on this issue here: https://lists.w3.org/Archives/Public/www-style/2017Mar/0001.html |
I am not sure that the |
We added a section with all the open questions to discuss. |
Thanks for the nice summary in the spec, of the current interpretations & open issues. I do like the idea of using But I would prefer that the replaced-element behavior is consistent with the shadow-DOM model of these replaced elements (that is, rendered as if the real DOM children are masked by a closed shadow DOM that is rendered in its place). I'm not sure I understand what that is: are the "contents" of a shadow DOM host the plain DOM contents, or the flattened shadow DOM contents? If the "contents" of a shadow DOM host are the regular-DOM child nodes, then (IMHO) it makes sense that:
However, if the "contents" of a shadow DOM host are the flattened-tree contents, after slotting true children into the shadow tree, then Another was of looking at the same end result would be to treat |
"display: contents" suppresses the box that the element would normally generate. Shadow DOM disappears by the time box-tree happens; the box tree is built based on the "flat tree", which has all shadows expanded out. So yes, for a shadow host, "display: contents" just strips out the host wrapper, but all the contents are left exactly the same, just "hoisted up" one level in the tree. We're pretty set on having replaced elements just go 'display:none' when you set 'display:contents', because they simply don't have any boxes below the replaced element's box; they're a black box as far as CSS is concerned. There's nothing to hoist! Note that |
Thanks for the clarification, Tab. I still think it's slightly confusing to have one layout rule for "native" shadow DOM (e.g., videos and complex form widgets) and another rule for custom web component shadow DOM, but that's consistent with them being very different from a DOM scripting perspective. However, I would prefer to have a consistent rule for all the replaced elements with fallback content, whether that's an
|
Again,
It's not even "one rule" for native shadows - The rule is totally just "is there a reasonable box tree underneath the element, that can be exposed when we strip the wrapper". All the replaced elements will get display:none regardless of whether they have fallback or not; the question is just what to do when their fallback triggers, and they stop being replaced. |
Couldn't you say the same about The only elements that sometimes fall back and sometimes don't, in a given browser, are |
No - the contents of progress/meter are fallback content, exposed to the a11y tree. They're meaningful in browsers that understand the element. I think meter/progress are similar to br/wbr - they represent some text content, even if they're rendered as magical things. They should probably be display:none as a result, we just want to make sure the WG agrees.
And embed/applet, I think. (If they can't, then whatever, they just display:none all the time.) |
Not really, see: https://w3c.github.io/html-aam/#el-progress Although there's still open debate about how best to expose
Yes for But regardless, my main point was : ideally, try to be as consistent as possible, rather than special rules for each different element type. But I recognize that we don't live in an ideal world. |
We went through the issue list in the new section at the Tokyo meeting. If there's anything remaining to go over, please re-add the agenda+ tag. |
Delegating to @MatsPalmgren. |
I discussed with @rune-opera, at first we thought So LGTM for resolving this bug. Further work could include upstreaming some of the logic to HTML, writing web-platform-tests, filing browser bugs... 😊 |
@zcorpan I'm not sure I follow. What sort of style are you envisioning async-loading? |
I mean something like https://github.com/filamentgroup/loadCSS |
Yes, I understand what async-loading is. What I'm not sure is what you think is racing against what. As in, what specific rules are being async-loaded, and what does the DOM look like? |
Oh, ok. If the behavior of http://software.hixie.ch/utilities/js/live-dom-viewer/saved/5186 for object first |
Hmm. Do UAs actually implement that "being rendered" requirement across the board? I'm pretty sure Gecko doesn't unless the type is a plug-in type (and even then, I think it may only affect plug-in instantiation, not the actual load, since the type is not known until you do the load), so both your testcases render the image in Gecko. Per the letter of the spec, every time an , or any ancestor, gets toggled to display:none and back it should redo the fetch for its |
https://drafts.csswg.org/css-display/#box-generation
w3c/csswg-test#1129
The implemented behavior seems to be that display:contents on replaced elements and form controls (not all of those are actually replaced elements) is ignored, as far as I can tell.
cc @rune-opera @tabatkins @fantasai
The text was updated successfully, but these errors were encountered: