Focusing on Focus

By  on  

What's up my a11y allies? Were you aware that the mouse and keyboard handle focus differently? Well it's true. Both handle them differently, and depending on what browser you are in also matters...a lot actually.

Focus is a crucial element to the usage and experience of the application we are interacting with. It is also the visual indicator of the element of an application we are focused on. There is a caveat to our focus pseudo class however, and that is our friend outline.

Before we get started, read this over and over until it is engrained in your mental space.

:focus {
    outline: 0;

This leads us in to our problem.

The Problem

There are times when a designer or art director could approach you and say that the outline that renders around certain elements of the page like links, or buttons, doesn’t look…good. It doesn’t match our branding and, well, can you please just remove it.

Developer versus designer.

And then being a developer, you follow up with, "sure I can remove it, but what alternative do you have to replace the outline?" If they look at you confused, then this is a great time to open up the communication of the importance of focus and what you can do collaboratively to make the experience accessible.

Reset & Normalize

If you have used Eric Meyer's reset, he removes the focus outline, but he explicitly says to define focus styles after the reset. What about normalize? If you go through the normalize css file and do a search for focus, you won’t find it. You will however find styles for :-moz-focusring. Currently, :-moz-focusring is not a thing so those styles that are being applied using the moz prefix might not work. If you go to the Mozilla Web Docs and search for :-moz-focusring there is a warning at the top that states this such thing.

Developer versus designer.

:focus-ring and :-moz-focusring seem to both be the same, neither are standards…yet. :focus-ring is currently in the CSS 4 spec and there is a polyfill which is the focus, no pun intended, of this post.

Importance of Focus

There needs to be a way for accessible and non-accessible users to be able to see where they are during interactions. A great example that I read about are login and password inputs. Focus indicates that you are on a password field after you input your login. It would suck if you went to start typing your password but had no visual indication of where you were actually typing your password.

What is Focus?

Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.

- Web Content Accessibility Guidelines

According to the Web Content Accessibility Guidelines 2.0, it states that any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible. Now that being said, it doesn’t say a blue ring, this is afforded by the browser, but is has to have some type of visual distinction.

Browsers & Focus

Browsers and focus.

Browsers handle focus differently as far as visual presentation goes, as well as functionality. They also focus differently from mouse to keyboard. I gave a talk illustrating these differences that you can find here ==> Focusing on Focus.

The Problem Continued

I touched briefly on :focus-ring earlier, it is currently in the CSS 4 spec, it landed on the 18th of May. It's not in any browsers yet, but there is a polyfill out there, one of which I am going to show you.

Focus ring CSS4 spec.

When you remove the default focus by assigning it a value of zero or none, you remove that for everyone, both keyboard and mouse users. Even others who use some type of assistive technology if I had to bet on it.

Some mouse users, on the other hand, don’t like having a focus-ring around custom elements, like custom buttons. This polyfill removes the focus-ring from these elements for mouse users, but adds it back in for keyboard users.

The Resolution

Focus-ring polyfill to the rescue! Essentially it is only these three lines of CSS, and using an already complete JS file. Pretty cool huh?

:focus:not(.focus-ring) {
    outline: none;

Below is a snippet from the JS file. What it means is anything that is focused, that does not have a focus-ring, set the outline to none. This caters to the mouse users. It sets a focus-ring to all the things in the whitelist in the JS file for both mouse and keyboards, except buttons. It turns off the focus-ring for buttons on mouse clicks, but still allows the focus-ring for keyboard users.

Focus ring JavaScript snippet.

The Support

Currently there is no support for :focus-ring at the moment, but I am pushing to get it implemented in all major browsers.

If you would also like to get it implemented, reach out to your favorite browser vendors and see what they say.

Awesome People!

A huge shoutout to Alice Boxhall, Rob Dodson, and all the fine people who have contributed to the focus-ring polyfill and continue to make it great!

More Info!

If you would like more info on this sweet polyfill, check out the GitHub here, focus-ring, and Rob Dodson's Ally Casts video here where he talks about it, Ally Casts.

Chris DeMars

About Chris DeMars

Chris DeMars is a ui developer for a wholesale mortgage company in Michigan. He is also an instructor and teacher assistant for the Ann Arbor and Detroit chapters of Girl Develop It. Chris loves coming up with solutions for enterprise applications, which include modular CSS architectures, performance, and promoting Web accessibility.

Recent Features

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

Incredible Demos


  1. Daniel

    Recently Roman Komarov wrote [a thorough article]( about this exact issue and proposed a viable html/css solution. I also added my take based on that article – [here](

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!