WICG / focus-visible

Polyfill for `:focus-visible`
https://wicg.github.io/focus-visible/demo/
Other
1.61k stars 123 forks source link

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

Open zelliott opened 3 years ago

zelliott commented 3 years ago

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).

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 https://github.com/WICG/focus-visible/issues/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 commented 3 years ago

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 */
}