:focus-vis­i­ble Is Here

One of the most important features of a website that is built with accessibility in mind is that it can be navigated with a keyboard. Most blind users and many users with motor disabilities rely on keyboard navigation, either with a standard keyboard or with a device that mimics the functionality of a keyboard. Providing strong visual indicators that highlight the element that currently has keyboard focus is therefore indispensable. In CSS, the focus styles for an element can be changed via the :focus pseudo-class.

a:focus {
  outline: 3px solid blue;
}

Hiding Focus Styles Is Bad Practice #

Besides accessibility requirements, there are also design considerations to be made, though: For some users, a strong visual focus indicator once they click an element with a mouse or touch it with their finger can be irritating or feel “clunky”. Often, the focus highlight is only visible for a short time just before a page change occurs. This is an additional visual change in the interface that users have to process and understand. Without the knowledge that this highlight around the element is actually an accessibility feature, people might be distracted or irritated. Sometimes, it is even perceived as an error. And while some designers certainly are far more sensitive to the aesthetic qualities of an interface than its users – and would be well-advised to get used to a bit more accessibility-oriented, contrasted designs –, it is still relatable that focus indicators might feel like an intrusive break in an otherwise carefully balanced visual design if the designers missed to actively style them.

Many clients and designers, therefore, insist that developers remove the focus styles altogether for purely aesthetic reasons.

a:focus {
  outline: none;
}

Don’t do this. It is an uninformed decision that actively excludes people and should not be an acceptable solution in 2020 anymore. We have to do better. But how?

One way out of this dilemma would be to consciously design the focus state of an element so that it is perceived as a natural part of the transition from one state of the interface to the next. This, however, is not always easy or possible.

:focus-visible to the Rescue

Luckily, there is now another option: The :focus-visible pseudo-class. According to the spec, “the intent of :focus-visible is to allow authors to provide clearly identifiable focus styles which are visible when a user is likely to need to understand where the focus is, and not visible in other cases.” Or, in other words, it lets you show focus styles only when they are needed, using the same heuristic that the browser uses to decide whether to show the default focus indicator:

/* Hide focus styles if they're not needed, for example, 
when an element receives focus via the mouse. */
:focus:not(:focus-visible) {
  outline: 0;
}

/* Show focus styles on keyboard focus. */
:focus-visible {
  outline: 3px solid blue;
}

In October 2020, Chrome 86 shipped with support for :focus-visible, Firefox also supports it since version 85, and older versions of Firefox support it via the :-moz-focusring pseudo-class since 2011. Support in WebKit is also coming, thanks to a recent initiative by Igalia. Edit: Support for :focus-visible shipped in Safari 15.4. So there is no need to hold back. You can start using :focus-visible now! Once more, progressive enhancement is your friend here. You can define regular focus styles for non-supporting browsers and then overwrite them for browsers that support :focus-visible.

:focus {
  outline: 3px solid blue;
}

:focus:not(:focus-visible) {
  outline: 0;
}

:focus-visible {
  outline: 3px solid blue;
}

You can try it out in this Codepen:

See the Pen :focus-visible Demo by Matthias Ott (@matthiasott) on CodePen.

Note that :focus-visible always applies in combination with :focus. So if you inspect it in Chrome’s Developer Tools, for example, make sure to tick both boxes to see the appropriate focus styles.

Focus Visible In Chrome Developer Tools

A Polyfill for Older Browsers #

If you need to support a wider range of browsers, including Safari, there is also a polyfill. It simply adds a focus-visible class to all focused elements in situations in which otherwise the :focus-visible pseudo-selector would match.

Once the script is added to your page, the code looks much like in the examples above. The only difference is that now we are using classes to define the visible focus styles in our CSS:

.js-focus-visible :focus:not(.focus-visible) {
  outline: none;
}

.js-focus-visible .focus-visible {
  outline: 3px solid blue;
}

If you decide to use the polyfill, make sure to pay attention to how it behaves in combination with your existing focus styles. It might still be a valid choice to only use the polyfill until Safari also adds support for :focus-visible. But regardless of which method you decide to use, it is fabulous that we now have a solution to a problem that was often “fixed” by developers and designers by making websites less accessible. :focus-visible now offers a solution that is accessible and makes users, designers, and developers happy.

Further reading #

-

This is the 62nd post of my 100 days of writing series. You can find a list of all posts here.

~

1037 Webmentions

  1. Also added it to the list of links at the bottom of my :focus-visible post from a while ago… ✅; matthiasott.com/notes/focus-vi…
  2. If you've been asked to remove "that ugly border" on links and buttons by someone who knows nothing about #a11y, you can still style your own focus ring with :focus-visible and not exclude people using keyboard navigation.👍 matthiasott.com/notes/focus-vi… + tpgi.com/focus-visible-…
  3. Maybe your code example could feature outline-color: transparent; instead of outline: 0;🙂Background: Windows High Contrast Mode and, let's say, IE11: nicchan.me/blog/tips-for-…
  4. Thanks a lot Marcus! This makes a lot of sense – I’ll change that! ????;
  5. Just updated my post on :focus-visible from last year and included the latest updates: Full support in Firefox 85 and progress on an upcoming WebKit implementation! 🎉
  6. 브;라;우;저;에;서; 키;보;드; 포;커;스;와; 마;우;스; 포;커;스;를; 구;별;해;서; 넣;으;려;나; 보;네;요;. matthiasott.com/notes/focus-vi…
  7. Just read a Reddit thread full of devs saying how `:focus-visible` isn't supported so don't bother. Now #Chrome 86 supports it so that's half the world. Plan ahead for new #a11y features, dum dums. Just added it to a client site. Nice guide by @m_ott here: matthiasott.com/notes/focus-vi…
  8. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  9. De :focus-visible pseudo-class is gelanceerd en maakt een deel van de :focus-stijlen overbodig. matthiasott.com/notes/focus-vi…
  10. :focus-visible is here, I don't really see the need for it myself I think we can manage fine with :hover :focus having accessibility and good UX, but knock yourself out... matthiasott.com/notes/focus-vi…
  11. :focus-visible 使;っ;て;、;マ;ウ;ス;と;キ;ー;ボ;ー;ド;の;フ;ォ;ー;カ;ス;ス;タ;イ;ル;を;コ;ン;ト;ロ;ー;ル;す;る;+ matthiasott.com/notes/focus-vi…
  12. :focus-visible Is Here matthiasott.com/notes/focus-vi…
  13. Shipped in Chrome 86 is `:focus-visible`, which is the pseudo class you're looking for when trying to style the focus ring (mainly used with keyboard navigation). 🔗 matthiasott.com/notes/focus-vi…
  14. :focus-visible Is Here by @m_ott — You may have been tempted to hide the CSS outline on focus (example: a:focus { outline: none; }, but this isn't good for accessibility. Thankfully there is :focus-visible to save the day! matthiasott.com/notes/focus-vi…
  15. :focus-visible Is Here · Matthias Ott – User Experience Designer matthiasott.com/notes/focus-vi…
  16. frontendfront: :focus-visible Is Here matthiasott.com/notes/focus-vi…
  17. Cet article concis de @m_ott résume ce qu’il faut savoir sur :focus-visible : matthiasott.com/notes/focus-vi… L’outline ne sera visible qu’à la tabulation et n’apparaîtra pas au clic. Les navigateurs ne supportant pas :focus-visible afficheront l’outline comme d’hab’. #a11y #UX #CSS
  18. We can now show focus styles only on keyboard focus. #a11y matthiasott.com/notes/focus-vi…
  19. 📣 New article by @m_ott matthiasott.com/notes/focus-vi… frontendbookmarks.com/css/selectors/…
  20. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  21. :focus-visible Is Here matthiasott.com/notes/focus-vi… #web #accessibility #CSS
  22. Une fonctionnalité intéressante pour ces situations où nous arrive pas à concilier le designer/le client et les exigences de l'accessibilité (un Joker en qq sorte) :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  23. 参;考;ま;で;。;🐶 matthiasott.com/notes/focus-vi…
  24. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi… SO excited about this!
  25. :focus-visible Is Here · Matthias Ott – User Experience Designer matthiasott.com/notes/focus-vi…
  26. 👉🏻 “:focus-visible Is Here” 🔗 matthiasott.com/notes/focus-vi… @m_ott on a CSS feature that may bring peace to the "keep it keyboard accessible" and "but I don't want ugly big blue outlines" debate.
  27. @adamwathan Have you seen this? I know you've been talking about focus states for @tailwindcss. matthiasott.com/notes/focus-vi…
  28. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  29. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  30. I wrote a tailwind plugin to support this in a backwards compatible manner: https://t.co/VB7Xeee5WB
  31. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  32. Ca va réconcilier ceux qui ne veulent pas afficher le contour au focus sur un élément, et ceux qui tiennent à leur affichage ! 👍 #css #focus #accessibilite #accessibiliteWeb #webAccessibility matthiasott.com/notes/focus-vi…
  33. 📝 :focus-visible Is Here 🔗 matthiasott.com/notes/focus-vi… #html #css #javascript #webdev #dailydevlinks
  34. :focus-visible is here matthiasott.com/notes/focus-vi… @m_ott #Accessibility #CSS
  35. :focus-visible Is Here by @m_ott #a11y #accessibility #browsers #css #focus #ui #usability matthiasott.com/notes/focus-vi…
  36. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  37. :focus-visible Is Here matthiasott.com/notes/focus-vi… #accessibility #a11y
  38. No, thanks for taking a look at it! ????; But would you say that it works as expected? I didn’t expect this post to get that much attention and am happy to hear about anything I might have overlooked so that people get to read correct information. 😅
  39. it does work as expected "in browsers that don't support :focus-visible it behaves just like it always does/did". hadn't had my coffee, and somebody asked me "so why is the demo not working in Firefox?" which got ME confused until i realised the demo WASN'T polyfilled too
  40. #CSS :focus-visible Is Here. Honestly, I never met any users who said that the focus was "clunky" in any tests, I think that removing the focus is mostly a "designer think it's breaking their design" problem. Still here's a solution :) matthiasott.com/notes/focus-vi…
  41. (ignore my last two, tweets, got confused thinking the codepen was already using the polyfill)
  42. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  43. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  44. Good reminder: ":focus-visible Is Here" #a11y matthiasott.com/notes/focus-vi…
  45. It’s really good news that `:focus-visible` is getting more browser support. It has recently landed in Edge and Chrome 86, so now we wait on Safari. 😄 matthiasott.com/notes/focus-vi… #CSS
  46. :focus-visible Is Here, by @m_ott matthiasott.com/notes/focus-vi…
  47. 🎉🥳 Hurray, :focus-visible is here! /* Hide focus styles, e.g. when an element receives focus via mouse. */ :focus:not(:focus-visible) { outline: 0; } /* Show focus styles on keyboard focus. */ :focus-visible { outline: 3px solid blue; } matthiasott.com/notes/focus-vi… via @m_ott
  48. matthiasott.com/notes/focus-vi…
  49. :focus-visible у;ж;е; з;д;е;с;ь;. М;а;т;т;и;а;с; О;т;т; о;б;ъ;я;с;н;я;е;т; п;р;и;н;ц;и;п; р;а;б;о;т;ы; п;с;е;в;д;о;к;л;а;с;с;а;, п;о;я;в;и;в;ш;е;г;о;с;я; в; Chrome 86, и; п;о;к;а;з;ы;в;а;е;т;, к;а;к; п;р;и; п;о;м;о;щ;и; п;о;л;и;ф;и;л;а; д;о;б;а;в;и;т;ь; п;о;д;д;е;р;ж;к;у; в; с;т;а;р;ы;х; б;р;...
  50. Н;е;м;н;о;г;о; п;р;о; :focus-visible в; с;т;а;т;ь;е; @m_ott: matthiasott.com/notes/focus-vi… И; в;ы;ж;и;м;к;а; к;а;к; в;с;е;г;д;а; н;а; к;а;н;а;л;е;: t.me/htmlshit/453 #HTML #frontend #CSS
  51. But since it would mostly affect power users who may know what focus styles are anyway, I think I could live with that.
  52. Perhaps not ideal for primarily mouse users who focus a form field and tab through several fields after that. They end up in "keyboard mode" even when using the mouse after that. The focus-visible polyfill handles it well in my experience.
  53. There's probably a bit of spec work involved. I think Gecko's focusring behavior of making outlines always visible once you've tab-navigated should be allowed by the spec. And then probably also some -moz-focusring behavior changes like making it match on some programmatic focus.
  54. Yeah, I implemented it behind a flag, but I think to ship it we probably want to make it a real alias of :-moz-focusring. I tweaked -moz-focusring behavior to be more sensible a while ago with the intention of doing it, but I haven't got to finishing that work.
  55. Thanks for the update and explanation, Emilio! Much appreciated! 🤗
  56. Yeah, the Mac focus-on-click behavior is in fact special, but it mimicks the platform convention (i.e., matches Safari).
  57. No worries! It happens all the time. :)
  58. :focus-visible has an implementation in Firefox either behind a flag or enabled only in Nightly, not sure. @Emilio might know more about if it could be enabled more widely or if there are blocking issues.
  59. Sorry mates; web development isn't my strong side. Those CSS properties look super useful, though! :)
  60. AFAIK, Firefox still only supports the feature under the name `:-moz-focusring` (see screenshot). But (!) on Mac, buttons still don’t have a focus style on click in Firefox. That’s what confused me a bit, when testing it. I’ll add this to the article… developer.mozilla.org/en-US/docs/Web…
  61. Oh yes ok I understand now. It's the Mac behaviour that made me think Firefox supports it by default. Thanks for pointing this out ????;
  62. Great news! I'm not sure what you mean with Firefox support because I use it for several weeks now. Or maybe I missed something ????;
  63. This’ll get designers who hate being able to see accessibility features off our backs!
  64. After being schooled by @patrick_h_lauke and @a_frontend_dev - it’s good to see this more on the wild
  65. I wrote this demo to solve this problem last week. I guess it’s now a polyfil codepen.io/jqim/pen/QWNZw…
  66. Hey Imran! Sure! I wrote the CSS myself, so no theme. The typefaces are Nudista by Suitcase Type Foundry and FF Spinoza by FontFont.
  67. Э;р;а; л;и;ш;н;и;х; и; г;л;ю;ч;н;ы;х; с;к;р;и;п;т;о;в; п;о;д;х;о;д;и;т; к; к;о;н;ц;у;! 😍 Д;а;ё;ш;ь; focus-visible!
  68. Websites hiding focus indicator "because it's ugly" has been a major issue on the web for long time. Hopefully with being able to distinguish keyboard/mouse focus, this antipattern will go away.
  69. Oh yes, 100 %! I’m also linking to your article. 😄 Maybe the screenshot in the tweet is incomplete in that regard… 🤔
  70. New link: ":focus-visible Is Here · Matthias Ott – User Experience Designer" — Direct Link: matthiasott.com/notes/focus-vi…

10 Reposts

ⓘ Webmentions are a way to notify other websites when you link to them, and to receive notifications when others link to you. Learn more about Webmentions.