CSS box-shadow vs outline

AntK picture AntK · Oct 1, 2018 · Viewed 7.2k times · Source

I have not been able to find a duplicate and you can find a bunch of blog posts which suggest to use box-shadow for element's focus state instead of outline as it is more flexible in terms of styling and it also follows the border-radius of the element you are styling unlike outline which always stays rectangular.

Is it considered a good practice to replace outline with box-shadow? Are there any caveats of doing so?

Answer

andrewmacpherson picture andrewmacpherson · Oct 2, 2018

There is a serious caveat to using box-shadow as a focus indicator. It doesn't work in Windows high-contrast themes.

When a Windows high-contrast theme is turned on, web browsers which support it will override certain CSS properties. Firefox, IE, and Edge do this, but Chromium-based browsers don't (as yet).

  • Foreground colours are overridden, to match the Windows theme. This applies to text, borders, and outlines.
    • Note that the CSS transparent keyword is a colour value, and it is also overridden here. A transparent border becomes visible.
  • Background colours are overridden, to match the Windows theme.
  • Background images are removed (including CSS gradients) in IE and Firefox.
    • Edge preserves background images, but applies a solid background colour to text. So parts of the background image may not be seen.
  • box-shadow is not applied, so it won't work as a focus indicator.

The following focus style will NOT be seen when a Windows high-contrast theme is in effect:

a:focus {
  box-shadow: 0px 0px 5px 5px rgba(0,0,255,1);
  outline: none;
}

There is an approach which can work however. Instead of removing the outline entirely, make it transparent while leaving the outline style and width in place. When a Windows high-contrast theme is in effect, box-shadows won't appear, but the outline will appear because the transparent colour is overridden.

a:focus {

  /* Visible in the full-colour space */
  box-shadow: 0px 0px 5px 5px rgba(0,0,255,1);

  /* Visible in Windows high-contrast themes */
  outline-color: transparent;
  outline-width: 2px;
  outline-style: dotted;
}