Designing button focus states for better usability
Tags: a11y, css, webdev, ux
Published: 2019-04-07 06:30:46

---
title: Designing button focus states for better usability
published: true
description: By using custom, accessible, focus states, we can make websites much easier to use for people that navigate using the keyboard.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/y9xsq3ozm59ndneeslpq.png
tags: a11y, css, webdev, ux
---

Let's say we're making a custom button. The designer hands off the design file, and we write some CSS to make it look exactly right. Pretty straightforward, right?

{% codepen https://codepen.io/eschafer/pen/qvJvZR default-tab=css,result %}

But wait — buttons have more than one state. The default state we just created looks good so far, but we need to make sure that it also looks noticeably different when it's focused.

**Many people exclusively use keyboards to navigate, and rely on the focus state to know where they are on the page.**[^1]

There's a huge variety of reasons why someone might use a keyboard over a mouse, and for many, using the mouse as a fallback just isn't an option.

When you navigate a page with the keyboard, you press tab to go through all the interactive elements on the page. If you have access to a keyboard now, go ahead and try it out. You should be able to easily see what's in focus.

If the focus state isn't visible (or hard to see), it's like trying to use a website with an invisible mouse cursor:

{% codepen https://codepen.io/eschafer/pen/moaKXV %}

There's no way anyone would think that'd be okay to push to production! But when we don't pay attention to our focus states, that's exactly what we end up doing.

This affects real people in the same way the invisible-cursor example might affect you. If you're sighted, there's also a good chance that *you*, personally, might end up relying on these focus states as you age (assuming you don't already). Let's fix this!

## Browser defaults

Browsers provide focus states by default. Here's what those look like on our custom button:

![How popular browsers render the custom button's focus state.](https://thepracticaldev.s3.amazonaws.com/i/sbcq3vpg0d7u9p92ytda.png)

I don't have vision problems, but most of those are *very* hard for me to see. It's even worse for people with low vision — for them, there's no visible difference between these focus states and the default button state.

## Designing a custom focus state

So what would we need to do to have a focus state that people can see? The main guidelines I use are:

1. If you're relying on color to signify a change in state, the [color contrast ratio](https://webaim.org/resources/contrastchecker/) between the default color and the focus color needs to be at least 3:1[^2].
2. Make sure that any outlines are thick enough to actually see. There aren't any official guidelines on this, but at least use something larger than 1px.

Here are some examples of accessible focus states:

{% codepen https://codepen.io/eschafer/pen/pYGNge default-tab=css,result %}

Ahh, much better! I realize that a lot of people like things like this to be subtle, but it doesn't really matter what something looks like if you can't use it. This was just a quick proof of concept, so I'm sure there's more creative ways to work within these guidelines that will also fit the aesthetic.

I hope this is useful!


### Related reading
- https://css-tricks.com/focusing-on-focus-styles/
- https://www.deque.com/blog/accessible-focus-indicators/
- https://hackernoon.com/removing-that-ugly-focus-ring-and-keeping-it-too-6c8727fefcd2
- https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html
- https://webaim.org/resources/contrastchecker/

[^1]: https://www.w3.org/WAI/perspective-videos/keyboard/
[^2]: https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html