If you're overriding browsers' default focus styles with
outline: none;, consider using
outline: 3px solid transparent; instead. This is a quick and easy way to remove the outline for most viewing modes, while preserving it for Windows High Contrast Mode users.
👋🏻 Hey there! Long time no see.
While I've been quiet, I've been working on a complete overhaul of the blog, giving it a fresh coat of paint and leveraging a completely different stack. As I was building out this redesign, I decided to try something I, admittedly, should have been doing much earlier: testing the page in Windows High Contrast Mode.
Windows High Contrast Mode, or WHCM, is an operating system-level setting that, when enabled, replaces the color schemes in supporting applications with a reduced palette. That palette could either be one of the presets or a custom scheme. Supporting browsers will override styles for backgrounds, borders, outlines, and more.
Tabbing through my site in High Contrast Mode, however, revealed a severe lack of focus indicators.
This isn't High Contrast Mode's default behavior. I had overridden the default focus indicators with
outline: none;, and replaced them with my own custom focus styles. These new, custom styles largely depended on changing elements' backgrounds, such as hollowing out the navbar links. Background styles are consistently the first thing to go in High Contrast Mode, however, and so we were left with no visual focus indicators.
And so, the problem at hand: restore focus indicators for High Contrast Mode users, while ideally maintaining the focus styles I already had for most viewing modes.
Maybe Media Queries Can Fix It?#
My first thought was to check for media query options for High Contrast Mode. After all,
prefers-color-scheme can be used in many browsers to detect system-level dark mode settings. High Contrast Mode didn't seem far off.
I stumbled upon the
-ms-high-contrast media feature, with settings for when High Contrast Mode is enabled, when it's set to black-on-white, and when it's set to white-on-black. When my attempts to use it were made in vain, I found that it had been deprecated since 2018 and was super experimental to begin with. Oops.
Since then, the World Wide Web Consortium has published a working draft with the
prefers-contrast media features, but these are still subject to change and don't yet enjoy wide browser support, if any. Perhaps one day.
Media queries wouldn't cut it for this problem.
Transparency Is The Best Policy#
I eventually found my solution in Sarah Higley's excellent Quick Tips for High Contrast Mode. Instead of clearing away the focus indicator with
outline: none;, I could do
outline: 3px solid transparent;
transparent keyword there is making the magic happen. When High Contrast Mode isn't applied,
transparent ensures that our focus outline is completely invisible. When High Contrast Mode is turned on,
transparent is completely, totally disregarded. Our users are greeted with a focus outline that's 3px thick, or whichever other thickness we pick. It's quick, easy, and memorable, and we don't have to finagle with media queries.
- I should have been testing for High Contrast Mode compatibility much earlier.
- Many of the resources out there for High Contrast Mode-compatibile styles are out of date, and recommending the now-deprecated
- Media query support for High Contrast Mode is currently in flux, but we should start to see significant headway soon.
- Nine times out of ten,
outline: 3px solid transparent;fits my use cases better than