Description
What is the issue with the HTML Standard?
Currently, the reading-flow PR specifies that if a reading flow item is display:contents, then two things happen:
- The item itself is treated as "not participating", so it gets put at the end of the reading order, arranged in DOM order with other non-participating things.
- The item is treated as a reading flow container itself, so its children follow it to the end of the order, and are arranged in the visual order specified by the parent reading flow container.
There was significant discussion on this behavior in the joint CSS/WHATWG meeting at TPAC about making this work better in several cases. Notably, it was considered bad if adding a "useless" 'reading-flow' value (applied to an element where DOM order and visual order are already consistent) could cause the reading order to now mismatch the visual order, because some of the items are in a display:contents subtree. For example, this markup:
<div class=flex>
<button class=item>A</button>
<div class="item container">
<button class=item>B1</button>
<button class=item>B2</button>
</div>
<button class=item>C</button>
</div>
<style>
.flex { display: flex; }
.container { display: contents; }
</style>
Currently, has consistent DOM, visual, and tabbing order: A, B1, B2, C. But if we added .flex { reading-order: flex-flow; }
, the tabbing order would change to A, C, B1, B2, despite the DOM order already matching the "flex-flow" order!
Conclusions reached during the meeting:
- The
display:contents
should not move to the end of the order as a "non-participating" item. Its children should go into the tabbing order according to their visual position as normal, according to whateverreading-flow
says.- If the
display:contents
element itself is focusable, it should go in the tab order immediately before the first of its children that are reading order items (according to thereading-flow
order). (So if you're tabbing backwards, it will be tabbed to after its first-per-reading-flow child.)- [not decided during the discussion] If it doesn't have any children that are valid reading order items, then it either:
- goes at the end as a non-participating item
- or just placed following its nearest preceding-in-DOM-order sibling that is a valid reading order item
- [not decided during the discussion] If it doesn't have any children that are valid reading order items, then it either:
- [This is contested and needs further discussion.] The
display:contents
item shouldn't be a reading order scope container. If layout causes other elements to interleave between thedisplay:contents
item's children, tabbing order should follow the reading-flow order strictly.- The argument for making it a group is that the a11y tree cannot reorder across siblings. That is, in the example markup from above, B1 and B2 will always be together in the a11y tree, and nested under their parent element if it is meaningful in the a11y tree as well.
- The argument for it being possible to change is that
tabindex
is already possible to jump back and forth across these scopes, without actually reordering the a11y tree. - Later in the day, during the CSS/A11Y joint meeting, we discussed this again. Some opinion leans toward "follow proper visual order" (aka allow skipping back and forth in the A11Y tree), but we were asked to explicitly tag the APA for more guidance.
- If the