Two-Colour Focus Indicators

Series: 11ty Theme

tl;dr: WCAG is now encouraging a certain focus indicator style, with two colours appearing outside the normal size of the item.

Series Description: However many years later, I have actually done something resembling completing the design of this site using eleventy aka 11ty! I'm sure there are still more things I'll decide to change later, but the general idea I'm pretty happy with. This series describes some of the main challenges I faced. You can navigate other posts in the series using the list of links in the sidebar.

The Web Content and Accessibility Guidelines has some documentation here that addresses making focus indicators more consistent and always easy to see.

One approach is to have the same focus style on the entire site. This might cause a problem in that the style will show up better in some contexts than in others, e.g. if it is a dark border, that won't show up as well in the menu with a dark background as it does in the white background main area.

Another approach is to have different styles depending on where it appears. This takes a bit more CSS work to define each possible combination, but on a lot of sites it is definitely doable. I have usually taken this approach. It does have a problem, too, though: it isn't as obvious that it is indicating focus when it is a different effect depending on where it appears. A user could start tabbing through the menu, seeing one effect, then get to the main content and suddenly it is a different effect. It might not be obvious that it is indicating the same thing - focus - because the user has started to think of one style as focus and now it is something else.

The solution is to have two colours, one light and one dark, across the entire site. That way, at least one of the two will stand out against any backdrop.

Here is the relatively simple version I have decided to implement on this site:

a,
button,
input {
  margin: 2px;
}

a:focus,
a:hover,
button:focus,
button:hover,
input:focus-visible,
input:hover {
  margin: 0;
  border: 2px solid var(--hover-border-color);
  outline: 2px solid var(--hover-outline-color);
  outline-offset: 2px;
  text-decoration: none;
}

The margins are maybe not necessary. Without them, each hover or focus will result in seeing the item shifting those 2px. In some contexts like the tag list in the sidebar, it might also result in the focus border/outline taking overlapping with other elements. By adding a margin to the default state for those elements when not focused/hovered, when it did become focused/hovered it didn't move. Arguably this isn't a good tradeoff, since it means that there is that little bit of extra space around every link, which maybe looks weird, but at least on this site I concluded I liked it better than the slight shifting with every focus/hover which I was finding overwhelming when scrolling across a lot of links on a page.

The other interesting question I explored here is whether focus and hover should have the same effect or a different one. On the one hand, if they were different, it does make it more clear if you are hovering or focus. On the other hand, for the most part, this doesn't really matter because you are probably only navigating either by keyboard or mouse, not both at the same time (other than when testing those effects maybe). Also, having the same effect for both has the benefits of less code to maintain and more consistency in experience. So, I decided to opt for having the same effect for both, which is now what I have always done in the past but seemed like the better decision.