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

Focus visible... but for aria-activedescendant? #247

Open
zelliott opened this issue Feb 8, 2021 · 1 comment
Open

Focus visible... but for aria-activedescendant? #247

zelliott opened this issue Feb 8, 2021 · 1 comment

Comments

@zelliott
Copy link

zelliott commented Feb 8, 2021

Motivation

I work on an app that renders highly visible focus indicators on keyboard input modality and subtle/no focus indicators on all other input modalities. We accomplish this today with a global singleton service that listens to focus events as well as keydown/mouse/touch/pointer events, and attempts to attribute the focus events to the appropriate input modalities. The service adds a CSS class with the current modality (e.g. .keyboard-focused) to the body, which then we can reference in our CSS styles. We do this instead of using :focus-visible because :focus-visible didn't have the requisite cross-browser support... although it looks like this may change soon.

However, one use case that :focus-visible (as well as this polyfill) does not support is aria-activedescendant. Consider the following use case:

Suppose I have a simple ARIA combobox where focus remains on the combobox text input and "focus/selection" is moved among the various [role="option"] elements within the combobox with aria-activedescendant. Suppose the combobox moves some class .is-active among the option elements in accordance with focus/selection (for styles that show which option is active). I'd like to render highly visible (i.e. conforming to all WCAG contrast requirements) "focus" indicators on the active option elements only on keyboard input modality. On other input modalities, I'd like to render a more subtle focus indication.

This isn't really possible with :focus-visible today (nor this polyfill).

  • The aria-activedescendant elements are of course not actually focused, so I can't write styles like .my-option-element.is-active:focus-visible { ... }.
  • The aria-activedescendant elements are also not guaranteed to be a DOM descendant of the focused element (e.g. the combobox case), so I can't write styles like .my-focused-element:focus-visible .my-option-element.is-active { ... }.

Solutions

One potential solution I've seen as a CSS proposal to to expose a user's input modality (potentially via media queries)... but it seems like it isn't seeing a lot of action these days.

Another potential solution is some kind of :focus-visible-within selector (mentioned in #151). If this selector existed, I could attach it to the body, and write styles like: body:focus-visible-within .my-option-element.is-active { ... }. Basically, :focus-visible-within would be identical to the .keyboard-focused global class I'm currently using in my app.

I'm curious what the members of this community think about this use case. Happy to spin up a demo if it helps facilitate discussion.

@Justineo
Copy link
Contributor

Justineo commented Feb 9, 2021

It seems that the suggested solution in #211 also works for your use case. With a hint for input modality on the body or root element, you can use something like below:

[data-interaction-mode="keyboard"] .my-option-element.is-active {
  /* focus styles */
}

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

No branches or pull requests

2 participants