Skip to content

[css-anchor-position-1][css-display-4] Anchor Positioning and Display Order #9356

@kizu

Description

@kizu

I was thinking a lot about how anchor positioning can be applied for popovers and tooltips, as well as other cases like sidenotes .

In a lot of these cases, the popover/sidenote/other content can be positioned absolutely in relation to some anchor, so the sighted user would get an understanding of how these elements are connected.

However, semantically, there is nothing that connects the anchor and the content associated with it, and the reading and tab order would not be correct, following the order in the DOM.

This issue is to discuss if we can somehow approach it and what could be the best way to do it. If there was a different issue that was already discussed, let me know!

Right away, I want to list other places where I found people mentioning the need to cover this aspect of absolute positioning:

  • There was an unanswered (from what I found; correct me if I missed it somewhere) question by @aardrian in the original visual order issue by @rachelandrew:

    Does this only apply in a flex/grid context, and if so, what about absolute positioning and floats?

  • There was a pre-anchor-position issue about a position: popover proposal, where @LeaVerou mentions the need to solve the accessibility issue for this kind of positioning:

    I would argue solving this is also an accessibility matter, since currently a lot of these solutions break accessibility (tabbing order), with the developer not always making up for it with script.

My Proposal

Now that we are thinking about providing a way to modify the reading order for flex and grid items via something like reading-order-items (#8589), what if we would also make a similar method apply for anchor positioning?

My idea is to make the anchor defined by anchor-default (and, thus, the implicit anchor defined in HTML via an anchor prop) the key to solving the reading/tab order for the absolutely positioned elements.

I think in almost every case, when we position something in relation to a specific anchor, we want the tab order to follow from the anchor to the positioned element and then back to the flow after the anchor.

Can we just do this by default? Do we need to make this opt-in while keeping the default DOM order, similar to how we keep the flex/grid intact? I'd argue for handling this by default and maybe providing a way to opt-out, as there is no fear of compat issues due to anchor positioning being new, and I really think almost all cases where we'd have a default anchor would want this behavior.

Examples

I went through the examples presented at TPAC (got the link from these minutes) and separated all the examples into three groups:

Purely visual

Some cases for anchor positioning can be used for purely visual purposes, like most of the examples in my article, or the positioning of the ::backdrop with an outline to create a “gap” in it.

I don't think there are any reservations for these cases — usually purely visual elements won't have any content to read or tab onto, so the behavior of anchor-default won't matter for these.

Popovers and Tooltips

In most cases, a popover would appear after a click on some button, and a tooltip would appear after hovering or focusing over some element.

A screenshot of a tooltip/popover from an editable text toolbar, allowing to choose the color to highlight the text with.

Whenever this happens and a popover/tooltip appears, from a keyboard standpoint, it would be logical for the next tab to land inside the next interactive element inside the popover/tooltip. Same for the reading order: I think it would be logical for it to follow into the popover as if it were placed in the DOM after the anchor element.

Main challenge: how to handle dynamic display and position of the absolutely positioned elements?

We would need to properly handle the case when we're on an element inside that popover, then we dismiss it in some way (from the keyboard or by pressing on the backdrop) — the popover closes either by being removed from the DOM, or by getting display: none, or maybe even losing the className that gave it the position: absolute, but keeping it in the flow (I can imagine footnotes working this way: we could yoink a footnote and show it as a popover, and put it back when dismissing).

The expected way we'd want this to be handled is for the “focus” to return to the anchor element, even if the association would be lost dynamically (anchor-default reassigned/unset).

Sidenotes

I think this example from @meyerweb's recent article is a good one to look at:

A sidenote next to the main text column, with its number aligned with the referencing number found in the main text column. There is a link present in the sidenote.
The sidenote is tightly associated with its reference, and there might be tabbable content inside the sidenote that we would want to access from the keyboard right away.

I think it would be completely logical for the tab order to follow the sidenote.

Reading order (and the whole semantics of the sidenotes — are they aside, are they a description?) is more uncertain. But as a sighted user, I find that I almost always go right away inside the sidenotes/footnotes, breaking the flow.

I cannot speak for screen reader users, but I imagine it is better to also get the sidenote content immediately after the sidenote in some way, given there would be some way to skip it. People who are more knowledgeable in this matter could weigh in on it — it would be very helpful!

Edit from 2023-09-16: Another aspect why making the sidenote follow its context immediately could be that for the sidenotes they often might not sense without their context. If a paragraph would contain 3 sidenotes, then you'd get read all of them in a row after the paragraph, you'd need to somehow remember which would apply to which place, or have some way to jump between them and the context? In any case, even if not skippable, I suspect the experience of having the sidenote content right after their context much easier to understand, though there really should be some way to be able to skip them — I'm not sure what could help with this as I'm not a screen reader user. Making the sidenote a description? Something else?

However, this might be a case where the out-out for the following the anchor-default could be helpful, as it would allow authors to more precisely control how they should such elements behave. Though, we could argue, that we could still utilize the anchor-default, and place the default anchor onto the paragraph in question (while utilizing a custom named anchor for the actual anchor), making it so the reading and tab order would follow after the paragraph.

Edge Cases

Multiple Positioned Elements

Multiple elements can target the same anchor. I'd say that if all of them using the anchor-default, the reading/tab should follow the anchor through all these elements in their DOM order, then back to after the anchor.

Conclusion

I think this is an important issue to think about now, so we won't create a case where anchor positioning would ship with subpar accessibility, making it harder to do things right afterward without breaking compat.

I am not an accessibility expert, so I could be incorrect in a lot of my assumptions, and I don't know if that behavior I'm talking about is easily implementable or has other issues to think about — that's why I invite anyone to comment, provide their use cases, and so on.


cc @tabatkins, @fantasai, @jensimmons

Metadata

Metadata

Assignees

No one assigned

    Labels

    HTMLRequires coordination with HTML peoplea11y-trackerGroup bringing to attention of a11y, or tracked by the a11y Group but not needing response.css-anchor-position-1css-display-4

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Tuesday morning

    Status

    unsorted FTF

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions