Open dizhang168 opened 1 month ago
We would like to discuss and resolve this issue at the next WHATNOT meeting. In particular, we would like to get HTML editors and implementers feedback on how to approach the display:contents
issue, such as:
cc: @emilio, @mfreed7
- Should display: contents specifications be included in HTML standard?
What do you mean by this in more detail? Is it about the sequential focus order specifically? If so, then I think the answer is yes, because HTML defines sequential focus order in general. Or is it about something else?
The question is specifically for focus navigation (although the same implementation should be used for accessibility tree and screen reader reading). Awesome, I also believe this should be included in HTML.
Regarding the a11y tree, the specific concern is reading order items are not DOM siblings of each other. If they are still siblings, then there is no issue with having intervening display:contents ancestors between the reordered items and the container. However, if they are not siblings, it can wreak havoc with the a11y tree logic because the display:contents parent elements may need to be in the a11y tree structure. In that case we can't always both keep things correct -- either the reordering must be restricted to DOM siblings, or the parent in the a11y tree would need to be changed from what it was in the DOM (this is hard to implement and I would argue is unexpected).
Summary from 2024/08/01 meeting: Display: contents being focusable are pretty rare cases to begin with. Given there are currently no preference nor use cases from web developers, we should prioritize what is easiest to implement and what wouldn't break existing API. Option 2 is the preferred option because, as mentioned above, this would avoid making huge/complex changes to the accessibility tree.
What is the issue with the HTML Standard?
The CSS Working Group has resolved to add the new reading-flow property (https://github.com/w3c/csswg-drafts/issues/8589, spec) to enable focus navigation in visual order for layout items that might not be displayed in source order (such as grid, flex and masonry items). Chromium is implementing the new property and opened a proposal on the needed HTML spec change. The explainer can be found here.
One remaining question is about
display:contents
elements in this context.display: contents
elements are elements that do not have a rendered style or layout. They can still be focusable if the tabindex attribute is set, per https://github.com/w3c/csswg-drafts/issues/2632 and https://github.com/w3c/csswg-drafts/issues/9230#issuecomment-2165098385. Howdisplay: contents
elements should be navigated is not decided yet (https://github.com/w3c/csswg-drafts/issues/9230).This issue discusses a few possibilities for handling
display:contents
elements with reading-flow.Option 1: Visit all items of a reading flow container together
All reading flow items are visited in the order they are defined by the layout algorithm for CSS reading-flow. Afterward, we visit all descendant display: contents elements, in case they are focusable. Only one focus scope is created per grid/flex container.
Spec change
Update steps of find the next item in reading order.
Pro: The elements are mostly visited in visual order.
Con: This would result in a mismatch with the Accessibility tree, which expects visiting siblings together and doesn’t want to combine descendants of different parents together.
Option 2: A reading flow item with display: contents is a focus scope owner
Here, we update the definition of a reading flow container such that a container with display: contents will result in a new focus scope. Within it, we will visit all the direct children of this container starting with the reading flow items and then the display: contents elements. If within those elements, a display: contents element is found, a new focus scope will be created.
Spec change
Add to definition of a reading flow container:
Replace step 1 of find the next item in reading order.
Pro: This would match with the Accessibility tree.
Con: We are more likely to get a mismatch between the visual and the reading flow order (see Example 2).
Examples
Example 1: An item has display: contents and has no element child
This will be displayed as:
However, neither div nor text node A is not recognized as a flex item and the order value is not used. Additionally, A is not focusable.
The visit order should be: C -> B.
Example 2: An item has display: contents, is focusable and has no child
This will be displayed as:
However, text node A is not recognized as a flex item and the order value is not used. The visit order should be: C -> B -> A.
Now, the tricky part when the display contents element has children.
Example 3: An item has display: contents, is focusable and has children
The rendered output:
Given option 1, we would visit in the order A -> B -> C -> D -> d1 -> d2. Given option 2, we would visit in the order div1 -> A -> C -> div2 -> B -> D.
Example 4: A Slot is focusable and has children
The rendered output:
Given option 1, we would visit in the order B -> D -> slot -> A -> C. This is because it recognizes the slot as a scope owner and its children should not be visited until that scope is created. Given option 2, we would visit in the order B -> D -> slot -> A -> C.
Note that we have already requested the feedback from Accessibility implementer @aleventhal. They prefer Option 2 because of how the accessibility tree is constructed. They also don’t think it is common to have display: contents mixed with non display: contents flex/grid items so this issue should not be common. However, just because a case is uncommon doesn’t mean we shouldn’t consider it. Especially because we want this feature to work well with web components. We have opened a blog post to request developer feedback.