Skip to content

Proposal: CSS reading-flow #10407

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

Open
dizhang168 opened this issue Jun 11, 2024 · 26 comments
Open

Proposal: CSS reading-flow #10407

dizhang168 opened this issue Jun 11, 2024 · 26 comments
Labels
addition/proposal New features or enhancements topic: focus

Comments

@dizhang168
Copy link
Contributor

dizhang168 commented Jun 11, 2024

What is the issue with the HTML Standard?

The CSSWG agreed to work on the new CSS property reading-flow: (w3c/csswg-drafts#7387, spec). Blink has been working on a prototype for how to change the sequential focus navigation order within a container that has reading-flow.

Our proposal can be found here:

Here’s a copy of the introduction:

Introduction

Focus navigation is the mechanism that allows users to navigate and access the contents of a website using their keyboard. Currently, this navigation follows the source order, aka the order the elements are defined in the DOM tree. This causes a disconnect when the elements are displayed in a different order, using a flexbox or grid layout, where the visual reading order can be different from the underlying source order using features like the order property.

The CSS Working Group agreed to solve this problem using the new CSS property reading-flow. This property allows developers to specify how items within a flex or grid container should be read. In this explainer, we are proposing changes to the WHATWG specifications to support this new property for sequential focus navigation. Namely, we propose adding a new focus scope owner and more steps to the sequential navigation search algorithm.

Note this feature will become even more valuable in the upcoming CSS Masonry, which uses an automatic layout method in which items are displayed in a harder-to-predict order.


I'm requesting feedback on this proposal and if agreed on, offer to do the spec work. Thanks.

@mfreed7
Copy link
Contributor

mfreed7 commented Jun 11, 2024

@emilio @annevk @rachelandrew feedback appreciated, thanks!

@annevk
Copy link
Member

annevk commented Jun 12, 2024

When I look at the last comment in the linked issue I don't get the impression the CSS WG decided on something here? Is this proposal the result of what some in the CSS WG were asking for?

@rachelandrew
Copy link

We're intending to discuss the linked issue at the f2f tomorrow morning. This proposal is in support of that. The WG has previously resolved to work on reading-order-items and the existing draft spec is here.

@annevk
Copy link
Member

annevk commented Jun 12, 2024

I see. Agreeing to work on something is very different from "The CSS WG has proposed ..." Clarifying that would be good.

The other thing that comes to mind here is #7054. Is that still being developed?

@bkardell
Copy link
Contributor

The other thing that comes to mind here is #7054. Is that still being developed?

It's moved into https://open-ui.org/components/focusgroup.explainer/ @travisleithead

@dizhang168
Copy link
Contributor Author

I see. Agreeing to work on something is very different from "The CSS WG has proposed ..." Clarifying that would be good.

Updated the above description to "CSSWG agreed to [...]", thanks for the suggestion.

@mfreed7
Copy link
Contributor

mfreed7 commented Jun 12, 2024

We're intending to discuss the linked issue at the f2f tomorrow morning. This proposal is in support of that. The WG has previously resolved to work on reading-order-items and the existing draft spec is here.

Thanks for linking to the spec. One thing that comes to mind is that the eventual WHATWG spec PR would be simplified if the CSS spec could have a defined term for the "reading order". That would avoid needing to re-define it as @dizhang168 has done in this section. The CSS spec has all of the info already, but it isn't listed in a way that could be referenced from the HTML spec, I don't think.

@rachelandrew
Copy link

I'm very happy to edit things into the spec that we think are usefully defined there, I'm not completely clear on what would make it easier to reference from the HTML spec (that's likely my lack of knowledge though) very happy to work through this to get things into the best place.

@annevk
Copy link
Member

annevk commented Jun 13, 2024

To be clear, I don't think @bkardell's response addressed my question. (But perhaps that was clear and people are still thinking about it?)

@keithamus
Copy link
Contributor

OpenUI has been regularly discussing focus groups and it is an active proposal being prototyped. I think they are a separate issue from this, however. Focusgroup is more about roving tab index patterns while as I understand it reading order is about adjusting the tab/AT cursor order based on layout. Both can co-exist and are distinct enough from each other that there isn't a lot of overlap.

@lukewarlow
Copy link
Member

lukewarlow commented Jun 13, 2024

reading-flow (reading-order-items) is relevant to the focusgroup idea imo. It will fall into the same trap that tabbing does today if you use flex and change ordering? Unless focusgroup just does its ordering based on tabbing's (with different focusability requirements). I think that there needs to be some thought put into both as to how they interact for sure.

It is still being actively developed.

@josepharhar josepharhar added addition/proposal New features or enhancements topic: focus labels Jun 21, 2024
@dizhang168 dizhang168 changed the title Proposal: CSS reading-order-items Proposal: CSS reading-flow Jun 28, 2024
@josepharhar josepharhar added the agenda+ To be discussed at a triage meeting label Jul 31, 2024
@dizhang168
Copy link
Contributor Author

Adding this proposal to the upcoming meeting so we can discuss with implementers:

@dizhang168
Copy link
Contributor Author

Summary from 2024/08/01 meeting:
Adding Reading Flow container as a focus scope owner make sense. The proposal should be updated to handle the cases of display: contents and position: absolute. Afterward, we can work toward opening a spec PR for the proposal.

@past past removed the agenda+ To be discussed at a triage meeting label Aug 13, 2024
@minorninth
Copy link

Can I ask if the intent is that text selection and caret browsing would be affected by reading-flow?

Caret browsing is some people's preferred method of navigation, and many screen reader users make use of a mix of caret browsing and other types of navigation (such as pressing tab) to navigate a page. If we "fix" the tab order but leave the caret browsing / text selection order to be the DOM order, is it possible we'd be making things more inconsistent and confusing?

@dizhang168
Copy link
Contributor Author

The HTML specification doesn't cover text/caret navigation right now and so neither is this proposal (for changes in the HTML spec). Right now, browsers can do what they think is appropriate for caret browsing so this behavior is out of scope.

Note there is this open CSSWG issue about this topic: w3c/csswg-drafts#12014

@minorninth
Copy link

Another question: can you explain why a reading flow scope owner needs to be a focus navigation scope owner? I'm told that this was done in order to prevent cycles, but I'd love to see a minimal example demonstrating why this is necessary.

I feel like what would be most intuitive to web authors would be that the tab index order would match what you'd get if you make a copy of the document and reorder the DOM to match the order implied by reading-flow. I'm wondering if there's some edge case I'm not thinking of that would make that impossible.

@dizhang168
Copy link
Contributor Author

Another question: can you explain why a reading flow scope owner needs to be a focus navigation scope owner? I'm told that this was done in order to prevent cycles, but I'd love to see a minimal example demonstrating why this is necessary.

A focus navigation scope owner is an element that scopes all its descendant elements to be visited together and re-orders its focus order based on rules in HTML specification. Since the “reading flow container” is meant to contain the focus order of its children/items together, it makes sense to make it a focus scope owner. It is not to prevent cycles. One benefit of making it a scope owner is that it will scope the tabindex values and we won’t have illogical visual jumping. For example,

<div id=container tabindex=1>
  <button tabindex=3>A</button>
</div>
<button tabindex=2>B</button>

Currently, the order of the above would be “container > B > A”
But with reading-flow, the tabindex is scoped and the order becomes “container > A > B” (visit all its children before moving to the next). This will also match the accessibility tree.

You can find more discussion talking about this design choice at tabindex vs reading-flow property and the lengthy discussion at TPAC 2024.

I feel like what would be most intuitive to web authors would be that the tab index order would match what you'd get if you make a copy of the document and reorder the DOM to match the order implied by reading-flow. I'm wondering if there's some edge case I'm not thinking of that would make that impossible.

Making a copy of the document and reordering the DOM could be expensive. I believe what we are proposing here will result in the same focus order. With the bonus that we are using focus navigation scopes, for the reasons mentioned above.

@minorninth
Copy link

To clarify, I didn't mean to actually copy the document and reorder - simply that this exercise would produce the tab index order that I think authors would expect.

Thanks for explaining the rationale behind scoping the tabindex values.

@minorninth
Copy link

Another question: is there anything in this proposal that would not be polyfillable? It seems to me that a JavaScript library could scan a document and dynamically update positive tabindex and aria-owns to achieve the same effect. Has that been considered, or is there something I'm missing?

@lukewarlow
Copy link
Member

Has there been discussion on how this would apply to arrow key navigation (ala OpenUI Focusgroup or a more real example customisable select's option picker)?

@dizhang168
Copy link
Contributor Author

Another question: is there anything in this proposal that would not be polyfillable? It seems to me that a JavaScript library could scan a document and dynamically update positive tabindex and aria-owns to achieve the same effect. Has that been considered, or is there something I'm missing?

The reading-flow feature changes the focus navigation order and the accessibility tree order of children in a layout modified container. As long as an element is keyboard focusable, it can use tabindex to set its order (so polyfillable). However, since the A11Y tree does not recognize positive tabindex, that part is not polyfillable. As for using “aria-owns”, I am not the most familiar, but it looks like it solves a different problem. In the reading-flow case, the items are already children so there is no need to re-assess the parent/child relationship.

Positive tabindex has other implications https://dequeuniversity.com/tips/tabindex-positive-numbers given that not everything on the page is going to be impacted by reading-flow (could result in jumpy navigation). This is why this feature is so important.

Note such a polyfill is tedious to implement because it would need to be re-updated with every layout change. That's not going to be straightforward for masonry or a dense packed layout, and complicated if you are changing the ordering due to available space.

Has there been discussion on how this would apply to arrow key navigation (ala OpenUI Focusgroup or a more real example customisable select's option picker)?

Good question! In an ideal world, it would be great if we can just put <select style=”appearance: base-select; display: grid; reading-flow: grid-order” focusgroup> and everything is done. Focusgroup is still in incubation though, so we can’t depend on that yet. For the customizable select, I took a quick look and the spec is purposely vague about how arrow focus navigation finds the next option. I did talk to @mfreed7 about this: we can and should support this.

@lukewarlow
Copy link
Member

lukewarlow commented Apr 10, 2025

Good question! In an ideal world, it would be great if we can just put <select style=”appearance: base-select; display: grid; reading-flow: grid-order” focusgroup> and everything is done. Focusgroup is still in incubation though, so we can’t depend on that yet.

So select effectively has an internal Focusgroup (like radio buttons and menus) so while that proposal isn't ready (might never happen) you wouldnt actually apply that attribute here anyway, I think the general question still applies though.

For the customizable select, I took a quick look and the spec is purposely vague about how arrow focus navigation finds the next option. I did talk to @mfreed7 about this: we can and should support this.

Great to hear!

@cookiecrook
Copy link

cookiecrook commented Apr 16, 2025

@dizhang168 wrote:

However, since the A11Y tree does not recognize positive tabindex, that part is not polyfillable.

I'm not sure what you mean. Are you intending something like "AT-based linear navigation order ignores tabindex, other than to determine whether an element is focusable or not"?

As for using “aria-owns”, I am not the most familiar, but it looks like it solves a different problem. In the reading-flow case, the items are already children so there is no need to re-assess the parent/child relationship.

But aria-owns is also intended to allow re-ordering of the existing children.

<ul aria-owns="one two">
  <li id="two">primary</li>
  <li id="one">secondary</li>
</ul>

That said, I would doubt much testing has been done to ensure aria-owns stability when it's modified with a responsive layout, so YMMV.

@cookiecrook
Copy link

cookiecrook commented Apr 16, 2025

Also, aria-owns does not affect selection or caret navigation, which seems to imply there will be a mismatch between types of navigation modes...

  • many screen reader users use a combination of linear AT, non-linear AT, linear arrow, non-liner arrow (e.g. next line), and tab-based navigation, which don't seem to be accounted for in the focus scope owner proposal
  • it's not clear to me if focus scope owner would result in a more or less predictable order in a timer-stepped switch interface... For example, some Switch Control users have their step speed set as fast as 50ms (1/20 of a second), so predictability is obviously critical.

@dizhang168
Copy link
Contributor Author

But aria-owns is also intended to allow re-ordering of the existing children.

Oh, right, thanks for pointing that out. I am not the most familiar with aria-owns and reading the docs, I thought it was for defining parent/child relationship only and didn't see its re-ordering benefits. Then I agree with you, the CSS reading-flow can be polyfillable for common cases using aria-owns and tabindex:

<div style="display: flex" aria-owns="one two">
  <li id="two" style="order: 2" tabindex=2>primary</li>
  <li id="one" style="order: 1" tabindex=1>secondary</li>
</div>

But, as mentioned before, I still think this polyfill would be hard to write for complex cases. Having this new CSS property will make keyboard and screen reader navigation much easier for users.

Also, aria-owns does not affect selection or carat navigation, which seems to imply there will be a mismatch between types of navigation modes...

Right. As explained in this comment, if we want to increase the usage of CSS property reading-flow to cover selection/caret navigation, maybe we can move the conversation to the CSS issue?

@cookiecrook
Copy link

Got it. Moved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: focus
Development

No branches or pull requests