Open kizu opened 1 year ago
I think it should be opt-in because I can imagine situations with something like a tooltip that appears in different orientations to the content/context element and therefore the reading order would vary depending on the instance possibly causing confusion.
I think it should be safe to assume that the tooltip's content always follows the context's content in the reading and tabbing order regardless of the tooltip orientation. I can't think of any real use case when someone will want otherwise.
Password hints (instructions) could be read before an input with better effect than following the input.
Using passwords for these kinds of hints will be bad UX for everyone tbh, not sure if it is worth breaking the experience of all other tooltips and popovers just for this use case.
With a way to opt-out, edge-cases like this one could be covered by the developers, but I think the goal should be to make the prevalent number of the most common use cases better, no?
I don't think we're talking about the same use case. But I digress. This is a problem developed by modern framework developers who didn't put elements in the "correct" document order. Making this a default behavior seems like an overreach regardless of any contrived scenarios where it helps or hurts the experience because that's often too subjective.
I think that the default behavior definitely needs to not change the tab ordering at all; the tooltip use-case probably wants it, but other use-cases (even using anchor-default) don't necessarily. For example, if you're just anchoring to some container, you probably don't want to be right after that container in the tab order (or at least, there's definitely enough doubt about your intent that we shouldn't change things by default).
There's also other focus-management work being done in HTML that I'd want to at least be consistent with (tho I'm not sure what the status of that work is now).
As such, I'd like to defer this to level 2. It would be great to have this work as easily as possible, but there's enough questions to answer that I don't want to make level 1 depend on it, and it will be safe to add in the future.
(Once Bikeshed switches to using anchor positioning for its link/dfn popups rather than JS-computed positions, it'll still need to keep its tabindex shenanigans, so it would be great if anchor positioning could somehow solve this!)
As such, I'd like to defer this to level 2. It would be great to have this work as easily as possible, but there's enough questions to answer that I don't want to make level 1 depend on it, and it will be safe to add in the future.
It seems to me that most of the example use cases where you do want to do "focus order fixup" are related to Popover use cases. That is mentioned in the OP here as well. It's important to point out that the Popover API itself provides exactly this focus fixup behavior, automatically. A popover automatically comes immediately after the element that invoked it in the tab order, regardless of where in the DOM that popover resides. That's spec'd here:
So I agree: it seems like a more general feature related only/specifically to anchor positioning could be deferred to level 2.
A few related items to consider...
doc-noteref
) in in DPUB-ARIA are subroles of link
... there are related concepts like footnotes with "back links" and glossary/term definitions. AT activation of the link the might be one way to determine whether it's relevant to render this subsequent content in linear reading order. click the link, read the footnote, continue with the sentence.... or if I don't click the link, just continue with the sentence. (ack: my example is somewhat specific to the footnote/glossary case.)
[Update Apr 18: the second bullet reference to Aaron's feature pitches included ARIA Annotations, which landed as part of aria-details, and a repeated content concept for page headers and footers. I don't think any of these related topics block the discussion of anchor positioning and display order.]
@cookiecrook Would you agree, then, that this is (a) probably not something we should be doing in all cases (automatically reshuffling focus order so a positioned element's focusable elements go immediately after its default anchor element), (b) something still under discussion in general, so nailing the details now isn't feasible, and (c) something we can switch on in the future in some way?
Sorry for the delay. I would've sworn I'd responded already. (Must've dismissed a draft.)
I don't think any of your options as phrased (a, b, or c) represent my opinion on the matter. I do think this concept is worth discussing now. I
(a) probably not something we should be doing in all cases (automatically reshuffling focus order so a positioned element's focusable elements go immediately after its default anchor element),
Your phrasing here may be too hypothetical to confirm or deny. Are there specific scenarios you are referring to? I gave some in the comment above to further spark discussion.
(b) something still under discussion in general, so nailing the details now isn't feasible, and
Under discussion doesn't negate feasibility IMO.
(c) something we can switch on in the future in some way?
I would advise against punting the problem to a future date.
Hm, okay, then let's step back and rephrase a little.
So, Anchor Positioning is a pretty generic layout feature (an elaboration on the existing position: absolute;
) that lets an element set its position relative to one or more other elements on the page. The common use-case is something like a popup, where the positioned element is being placed adjacent to one element in the page. But there is a wide variety of other things you can achieve with this functionality, where the tab-order relationship between the positioned element and the anchors is either unclear, or there is in fact no such relationship. For example, you can use a container element as an anchor, and position yourself in one of the corners - this is indistingishable, stylistically, from the popup case, but almost certainly doesn't want the popup to have some particular tab-order relationship with the container.
Further, for that common use-case I mentioned, the Popover API is intended to capture most such examples; further elaborations like the interesttarget
proposal do even more. Using Popover or its sub-features does clearly establish a semantic link between the invoker and the popup, which we do rely on for tab-order fixup - that's already built into the feature.
You mention a few other features, like ARIA Annotations, which similarly might use anchor positioning to style themselves, but which don't rely on the anchor positioning to establish the semantic link between the two elements; instead, it's established by the other feature.
So, since the generic CSS behavior can do a whole lot of things, and doesn't consistently establish a clear semantic relationship, I'm arguing that we do not want to attempt to infer any such relationship from the styles and reshuffle tab-order accordingly. Instead, we want to rely on more targeted features like Popover, ARIA Annotations, etc. to establish such linking, and those features will usually simply use anchor positioning for their own styling.
Does this sound reasonable? Or do you have other examples you're thinking of where a semantic relationship would be conveyed solely (and ideally reliably) by the presence of some detectable pattern of Anchor Positioning usage, and there's no other, more reliable/preferable way to establish that relationship (in markup, script, or otherwise)?
Thanks for the additional explanation.
While I agree that anchor positioning by itself is not sufficient to establish the type of semantic relationship between elements, the proximity-based rendering often (frequently?) would convey a navigational relationship... In particular for the reading order (including tab loop if elements are focusable), a sighted user could infer a logic to the reading order based on the anchored position relationship... And I think that's the intention of @kizu's proposal.
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.
I'm sure we could come up with a hypothetical example that doesn't fit this, but Roman's suggestion does make sense to me as a default or option.
As a counter-example, and a demonstration of how we can't reasoanbly infer these relationship, consider a big grid of data, and the sorting controls are a positioned element anchored to it, just outside the grid and flush against its top edge
.data-table {
anchor-name: --data-table;
}
.sort-controls {
position: fixed;
position-anchor: --data-table;
inset-area: top span-right; /* outside the grid, this bottom edge against the grid's top edge */
justify-self: start; /* left edge aligned with the grid's left edge */
}
Here, you probably want the sort controls to show up in the tab order before the contents of the big data grid, by default.
Contrast that with this commentary case:
.item {
anchor-name: --item;
}
.comment {
position: fixed;
position-anchor: --item;
inset-area: top span-right;
justify-self: start;
}
Here, you probably want it to read/tab the item's contents first, then go to the comment.
The styles in these cases are exactly identical, the difference is purely contextual, not expressed in the style system at all. The correct thing to do is annotate these elements appropriately: in the first case, probably just aria-controls
on the positioned element, pointing to the data grid, and maybe aria-owns
on the grid pointing to the controls; in the second case, aria-details
on the item, pointing to the tooltip, and role=comment
on the comment.
I simply don't think that either case can be reasonably inferred from the style system. I tried really hard to infer similar relationships from the style system when working on CSS Toggle States, but that also ended up being too complex and ambiguous to do anything useful. The final conclusion there was that we needed more targeted proposals that did naturally impose specific semantics - things like popover, details
groups, and the in-early-development carousel-related properties.
Note that "as an option" is still on the table; what I'm pushing back against is "as a default". If we want to make tab ordering more controllable from CSS, with some explicitly-designed properties, I think that's a great idea. But it goes beyond Anchor Positioning and is instead a separate feature that could be used much more broadly.
Typically I see sort controls near a specific header cell (Excel, Numbers, etc), so in that design on the pattern you mentioned, I would expect the focus order of the floating control to follow the header cell.
If you have a visual mockup in mind of the sort control outside the grid, it may be helpful to share the illustration so that we’re visualizing the same control. Thank you.
Note that "as an option" is still on the table; what I'm pushing back against is "as a default". If we want to make tab ordering more controllable from CSS, with some explicitly-designed properties, I think that's a great idea. But it goes beyond Anchor Positioning and is instead a separate feature that could be used much more broadly.
I would hope that such a feature would be general, and would handle similar situations with "pure" absolute or even relative positioning. Right?
E.g.
<div style="margin-top: 2em;">and then this <button>second</button></div>
<div style="position:relative;top:-3em;">Please click this <button>first</button>,</div>
Yes that's definitely a strawperson example, but it illustrates the issue that positioning can already be used to display things out of order. So if there's a feature to fix that, it should apply to all positioning modes.
The CSS Working Group just discussed [css-anchor-position-1][css-display-4] Anchor Positioning and Display Order
.
Summary: This needs to be addressed in HTML; keeping the issue open for tracking and so that we can update the spec with appropriate guidance and cross-references.
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:
position: popover
proposal, where @LeaVerou mentions the need to solve the accessibility issue for this kind of positioning: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
(https://github.com/w3c/csswg-drafts/issues/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 ananchor
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 anoutline
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.
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 theposition: 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:
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 adescription
?) 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!
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 theanchor-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