Skip to content
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

tabindex vs reading-flow property #10642

Open
tabatkins opened this issue Sep 24, 2024 · 3 comments
Open

tabindex vs reading-flow property #10642

tabatkins opened this issue Sep 24, 2024 · 3 comments

Comments

@tabatkins
Copy link
Contributor

What is the issue with the HTML Standard?

Currently, the reading-flow PR has the behavior that 'reading-flow' makes the element a scope container for tabindex, and within that scope, tabindex ordering is consulted first, with visual-order giving tiebreaking between identical values. (I think that's a correct summary of the current behavior?)

During the CSS/WHATWG joint session at TPAC, we concluded that it would be better to make tabindex more subordinate to 'reading-flow'.

The exact proposed behavior is:

  1. On the "reading flow items", tabindex is ignored for ordering purposes (it still makes the items focusable as normal, etc). 'reading-flow' is explicitly taking over the ordering of these elements.
  2. On the descendants of the "reading flow items", tabindex's ordering behavior is scoped to that reading flow item subtree. (Aka the reading flow items are scope containers for tabindex, like the spec currently defines for the "reading flow container".)

The participants in the discussion believed this has a more predictable and desirable behavior for authors. Ignoring tabindex's ordering effects on the reading order items themselves seems useful; it allows authors to use tabindex to define one particular ordering, in particular a non-visual one (or one for legacy UAs), and then let 'reading-flow' override that in other cases.

Similarly, having each item be a scope for their descendant tabindexes seemed to better match the mental model we were working with, where 'reading-flow' effectively rearranges the reading order items.

@dizhang168
Copy link
Contributor

From the conversation at issue 10533, there are some good feedback about tabindex. Right now, tabindex is already ignored in the accessibility tree. This causes confusion for users when they switch from using focus navigation to the screen reader. Further, positive tabindex values are bad because it causes confusion to the users and causes the order to jump around. Developers historically have also not been reliable about updating the tabindex value when the visual order of elements change, because they are unfamiliar with this attribute and accessibility best practices in general. Since we should aim to have the screen reader and the visual order match as much as possible, ignoring tabindex on reading-flow items does make sense.

What I am unsure about is the second part of the proposal:

On the descendants of the "reading flow items", tabindex's ordering behavior is scoped to that reading flow item subtree. (Aka the reading flow items are scope containers for tabindex, like the spec currently defines for the "reading flow container".)

I would argue that this change would be more confusing to the users, since most people are not familiar with the concept of focus scope owners. They would expect the HTML tabindex attribute to work across the document and would find this restriction weird.

For example, should we visit all elements with tabindex=2 together?
Or visit each reading flow item scope individually (go from A -> A2 -> A1)?

<style>
.box {
  display: grid;
  reading-flow: grid-order;
}

</style>

<div class="box" id="w" tabindex="0">
  <div id="A" tabindex="0" style="order: 3">
    <button tabindex="1">Item A1</button>
    <button tabindex="2">Item A2</button>
  </div>
  <div id="B" tabindex="0" style="order: 1">
    <button tabindex="1">Item B1</button>
    <button tabindex="2">Item B2</button>
  </div>
  <div id="C" tabindex="0" style="order: 2">
    <button tabindex="1">Item C1</button>
    <button tabindex="2">Item C2</button>
  </div>
</div>

I think there are too many possibilities for complexity. Considering the existing limitations with positive tabindex, I would prefer not making reading flow items focus scope owner and instead make their descendants also ignore tabindex.

@dizhang168
Copy link
Contributor

dizhang168 commented Oct 22, 2024

I take back my objection above. I looked for existing web developer feedback and there are no existing issues asking to use tabIndex weirdly like in the example above. Instead, what I see most is people setting the same tabIndex on grid/flex item and its descendants so they can have a behavior similar to reading-flow. We are adding complexity, but it can be easily documented through HTML standard and will overall be more intuitive. The current proposal is good because the CSS reading-flow property was always meant to only affect the reading flow items, not its descendants. I expand more on my research and how to change the spec here.

High level, here is how this proposal changes the specification:

A reading flow scope owner can be one of 3 cases:

  • A reading flow container scope owner
    • A reading flow container (has flex/grid and reading-flow properties)
    • A display: contents element, whose layout box parent is a reading flow container
  • A reading flow item scope owner
    • A reading flow item, whose layout box parent is a reading flow container but itself is not

Elements in reading flow container scope owner follows a reading-flow focus navigation scope. This takes the layout order into account to re-order the reading flow items. If a reading flow item has a positive tabindex, set it to 0.
Elements in reading flow item scope owner follows a tabindexed-ordered focus navigation scope.

For example:
image

Edit: Updated the example with different tabindex values

Here, the focus order is:
Wrapper -> A -> B -> Display: contents -> F -> C -> E -> D -> H -> position: absolute -> G

@mfreed7 mfreed7 added the agenda+ To be discussed at a triage meeting label Oct 22, 2024
@past past removed the agenda+ To be discussed at a triage meeting label Oct 24, 2024
@dizhang168
Copy link
Contributor

Here is a Shadow DOM example, with the same focus navigation order. The wrapper is a shadow host and the display: contents div is a slot. Its content are slotted from the light DOM.
Because a slot has CSS display: contents, it will follow a reading flow container scope navigation.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants