Skip to content

Instantly share code, notes, and snippets.

@robdodson
Last active May 5, 2021 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robdodson/af9ff157bbdfa6ab5f06fac46854f6ee to your computer and use it in GitHub Desktop.
Save robdodson/af9ff157bbdfa6ab5f06fac46854f6ee to your computer and use it in GitHub Desktop.
:focus-visible meta keys

Explainer

This is discussed in this issue but it looks like we updated the polyfill and forgot to update the spec :(

How we arrived at this decision

Slack asked if we should only match :focus-visible on tab / shift-tab (or in cases where the element should always receive it, like an input). Twitter chimed in with a +1. They both said essentially that when folks hit keyboard shortcuts that move focus, it's confusing to see the ring show up.

Alice pointed out that it's just as likely for a keyboard user to use those same shortcuts and it might be confusing for them to not see the ring.

But we all agreed to try the tab/shift-tab only approach in this PR. The PR also added the modifier key checks but I don't think we actually discussed it at the time.

Using only tab/shift-tab led to problems because it didn't match if folks were using arrow keys to navigate radio buttons. And many ARIA patterns also call for supporting Home, End, PageUp, PageDown, etc. and it didn't match there either.

We thought about trying to check for any of the ARIA roles but this started to feel like playing whack-a-mole so I suggested reverting the behavior which we eventually did in #118.

In the end Alice and I discussed the issue which seemed to be that apps want to use keyboard shortcuts to manage focus. So we decided that if the user is pressing a keyboard shortcut that contained a meta/modifier key to move focus, then we would not match :focus-visible. However, if they were just using something like Esc (or any keypress without a meta/modifier key) to move focus, we would match :focus-visible. This allows you to hit Esc to close a dialog and see the focus indicator on the control that originally opened the dialog.

Aside: Part of the problem might be that we use tabindex=-1 to manage focus and this is a bit of a hack. Sometimes you really just want to move the focus navigation start point, but there's no API for doing that so developers have to overuse tabindex.

Questions / suggestions

Suggestion from Ryosuke

What makes more sense to me is deciding it based on whether some event handler or the default event handler did something in response to a key event or not. Namely, EventHandler::internalKeyEvent returned true.

This is a really interesting idea, and not something the polyfill had the ability to do. The reason I like this idea is because many apps have shortcuts that don't use modifier keys so it would still work for them. The one downside is if the user is pressing Esc to close a dialog then it would not match when focus is returned to whatever control opened the dialog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment