Open zcorpan opened 8 years ago
https://github.com/w3c/csswg-drafts/issues/540 is now resolved as follows: https://drafts.csswg.org/css-display/#unbox
Stumbled into this one for innerText. There's a wpt relying on "being rendered" being true for display:contents. innerText is spec'ed to return textContent for elements not being rendered.
Gecko considers display:contents to be rendered for textContent. Another reference to "being rendered" in the HTML spec where this matters is https://html.spec.whatwg.org/multipage/browsing-the-web.html#scroll-to-fragid:being-rendered
For that case, Gecko does not scroll to a display:contents fragment.
@emilio do you know how consciously this is done in Gecko?
Oh, I somehow missed that mention... But the answer is "Gecko's innerText impl was a bit bogus", see https://github.com/web-platform-tests/wpt/issues/12580.
In the CSSWG issue linked above (2362), it turned out that treating elements with display:contents
as "not being rendered" conflicts with the general rule and intent that CSS display
other than none
shouldn't affect the semantics and interactivity of the element. Specifically, it turns off the focusability of the otherwise focusable element (at least, removes it from the tab focus sequence).
I believe that treating an interactive element that has visible subtree and can be activated through it as "not being rendered" is confusing and counter-intuitive. Wouldn't it be better to revisit this definition (or change the focusability criteria from "element has associated CSS boxes" to something like "element or its subtree has any visible/interactive parts")?
Revising the focusability criteria seems reasonable to me, but I'd like to to be as well-defined as possible. Moving from "has CSS boxes" to "has any visible/interactible parts" seems like a step down in rigor.
It's also possible that this problem occurs more than just for focus, in which case the better revision may be to change the definition of "being rendered".
I found the usage of the "box tree" term in the spec (in the section about Focusable areas). Maybe it can be reused for "being rendered", like the following?
An element is being rendered if any of the element itself, its descendant nodes, or pseudo-elements associated with the element itself or its descendant nodes, generate a box or text run in the box tree.
Revising the focusability criteria seems reasonable to me, but I'd like to to be as well-defined as possible. Moving from "has CSS boxes" to "has any visible/interactible parts" seems like a step down in rigor.
Yeah, that is true. Also, it seems a bit weird to define that an element with display: contents
is focusable, fwiw. While I get the sentiment, per definition elements with display: contents
generate no boxes, which means that they generate no overflow, no background, no outlines...
I wouldn't know how to implement a "focusable display: contents
element", except hacking up the whole layout engine to display some kind of outline on descendants that contributed to some overflow area? Which overflow area should that contribute to, I don't know... Descendants of display: contents
elements can be all over the layout tree.
Although at first glance I am sympathetic, it seems that debate has already been had at https://github.com/w3c/csswg-drafts/issues/2632, and the conclusion is that they should be focusable, even if you don't draw any outline around them.
In other words, break it down into observable consequences:
:focus
, but maybe they'll put something like a background or border or outline which doesn't work on display: contents
, and if so, that's fineDoes https://github.com/w3c/csswg-drafts/issues/2632#issuecomment-495360508 match implementations though? If browsers use the box tree and there's no box tree, many of these things will be affected unless they are somehow specifically catered for (likely by creating some special box), so I'm not sure the conclusion there is fully accurate.
The exact problem is that there is a box tree in case of display:contents
(totally unlike the display:none
case!). It only misses just one box (the box for element itself), but all other boxes in it remain fully visible and interactive (they can be clicked and this activates the element through event bubbling). However, the definition of "being rendered" and related concept of focusability are currently tied to this one box, not the presense/visibility of the box tree, and this discrepancy currently leads to behavior which is counterintuitive for both authors and users. So maybe there are better options for this case than to tie focusability etc. to that one box?
CSSWG now has a resolution that, for accessibility reasons, display:contents
elements need an outline rendered around their displayed contents when focused:
RESOLVED: Outline of 'display: contents' is propagated to children for painting (for a11y on focus);
IMO, this clearly implies that display:contents
elements must be focusable, and thus should be considered rendered.
Maybe the it would be sufficient to update the definition of "being rendered" like the following?
An element is being rendered if it or its content has any associated CSS layout boxes, SVG layout boxes, or some equivalent in other styling languages.
What is "content"?
I tried to find something short for something like "any of the element's inclusive descendants or their CSS generated content pseudo-elements". I agree that it was too vague for the definition.
"being rendered"
An element is being rendered if it has any associated CSS layout boxes, SVG layout boxes, or some equivalent in other styling languages.
To me, that seems to imply that display: contents
shouldn’t affect it as descendant items still generate layout boxes as normal.
It seems that the term "a box associated with the element" is quite ambiguous and still needs some clarification. On the one hand, it can be read as a broader synonym for "a box generated by the element" (that sounds more natural for CSS devs), but applicable to SVG and (largely hypothetical) "other styling languages".
On the other hand, the CSS Display Level 3 actually does use the term associated, but it's not defined normatively, and seems to mean different things in different contexts. E.g. in the phrase
An anonymous box is a box that is not associated with any element
it seems to mean more-or-less the same as "generated by" (otherwise, we would say that an anonymous box is "associated" with the parent element which would generate more than one box in this case). However, later in the Glossary section we have the following definition (emphasis mine):
containing block A rectangle that forms the basis of sizing and positioning for the boxes associated with it (usually the children of the box that generated it)
which seems to imply that many boxes can be associated with one particular aspect of the element, and the box subtree of the element can be considered somehow associated with the parent element (at least, in some circumstances).
"associated" isn't a term of art in that spec, it has its regular English meaning.
(Sorry for the drive-by correction; I'm happy to help provide wording guidance here, but I'm not sure exactly which definition y'all wanna fix.)
My idea was to update the "being rendered" definition to treat any element with the non-empty box tree as rendered. This way only elements with display:none
(in the CSS terms) would be considered non-rendered, and there will be no "non-rendered elements that the user still can see and interact with" that confuse authors.
Sounds like we need a more precise definition of associating a CSS box with an element in CSS?
any element with the non-empty box
That still sounds ambiguous. What does it mean for an element to be with a non-empty box tree?
It seems that the HTML spec definition tries to be more general, considering SVG boxes and "some equivalent in other styling languages" along with CSS boxes, so updating the CSS definition would probably be not enough. Changing the HTML definition seems more reliable to me.
My suggestion was to replace the word "element" in the current definition of "being rendered" with a new term/phrase that would include
::before
) of the element or its descendant elements...i.e. anything that is somehow displayed to the user and for what the element in question is an ancestor. With this change, the definition should become unambiguous regardless the exact interpretation of the "box/element association".
I don't think HTML's definition needs to be more general and CSS already needs to deal with SVG one way or another. We should strive to simplify that setup, not make it appear more grand than it really is.
If it's possible to use CSS as direct reference in the "being rendered" definition, maybe it can be defined like "An element is being rendered if its CSS display
is other than none
"?
That doesn't work for descendants of display: none elements.
Valid point. Then maybe something like
An element is being rendered if any of its shadow-including inclusive descendants or their CSS pseudo-elements has associated CSS layout boxes, SVG layout boxes, or some equivalent in other styling languages
would work?
Are there any objections to redefining "being rendered" as following?
An element is being rendered if any of its shadow-including inclusive descendants or their CSS pseudo-elements has associated CSS layout boxes, SVG layout boxes, or some equivalent in other styling languages
I made a quick attempt to fix Chromium bug 1366037 which relates to focusability of display:contents
elements..
It turned out that display:contents
elements not being focusable was being tested in 3 places in Chromium's test suite. The one that was in WPT was specifically testing display: contents
, but the other two (not in WPT) were testing that the <slot>
element is not focusable.
I'm curious if folks here think that a <slot>
element becoming focusable is an expected consequence of display: contents
elements being focusable, or if <slot>
should be unfocusable through some other mechanism.
As a consequence of being display:contents. That is, I would expect tab to focus the slot for:
<!doctype html>
<div id="host"></div>
<script>
let root = host.attachShadow({mode:"open"});
root.innerHTML = `
<style>
slot {
display: block;
width: 100px;
height: 100px;
background: red;
}
slot:focus {
background: green;
}
</style>
<slot tabindex="1"></slot>
`;
</script>
That works in both Safari and Firefox, but not in Chrome. Without checking any specs, I'd say that's a Chrome bug.
It's worth noting that w3c/csswg-drafts#2632 concluded that elements with display: contents
should be focusable, which contradicts the above. (Note that in Chrome, the bug is specifically about being tabbable, and not more generally about being focusable.)
display:contents
https://drafts.csswg.org/css-display/#valdef-display-contents
"being rendered"
https://html.spec.whatwg.org/multipage/rendering.html#being-rendered
So an element that is display:contents is not "being rendered". Check the uses of "being rendered" if that makes sense.
Related: https://github.com/w3c/csswg-drafts/issues/540