Interactive elements
Introduction
Many users, especially people with motor disabilities or visual disabilities, rely on a keyboard to navigate the web. These people need visual focus indicators to enjoy the web.
It is common to hide the default focus indicator because it's ugly and different across browsers. That's okay, though. What isn't okay is to not build an alternative.
We must provide accessible focus states on our apps.
button:focus {
/* It's okay to do this... */
outline: none;
/* ...if we build a custom indicator */
box-shadow: 0 0 3px 3px tomato;
}
Exercise
In the exercise page, there are a couple of interactive elements. However, we can't easily access them through the keyboard.
π― Goal: Make all interactive elements accessible by keyboard, using :focus
.
π Tip: You can use Tab
and Shift + Tab
to go forward and backward respectively across the interactive elements.
There aren't any explicit design requirements, so you can go free-style! Adding some opacity or changing the color are common design approaches.
Safari Note: By default Tab
doesn't work on links and buttons. Activate those in Settings > Advanced > [β] Press tab to highlight each item on a web page.
Firefox Note: By default Tab
might not work on Mac. Do this: Type about:config
in the URL bar. Then on the preferences bar, type accessibility.tabfocus
, create a new "integer" pref, and set it to 7
. If needed, restart Firefox.
Bonus
#1.1 Focus only when using the keyboard
Another common reason to hide the focus indicator on buttons and links is that the focus indicator is triggered when we click them.
The good news is that we can ignore the focus when using the mouse and show it only when using the keyboard, using :focus-visible
pseudo element!
/* Remove the outline for mouse users with modern browsers */
button:focus:not(:focus-visible) {
outline: none;
}
/* Show the focus when interacted with keyboard */
button:focus-visible {
outline: 3px solid tomato;
}
π― Goal: Add :focus-visible
to the interactive elements.
π Toggle hint about inputs
In inputs, the focus-visible is always triggered, even on click. That's not a bug, but rather the spec's expected behavior.
UA (Browser User Agents) typically display focus indicators on text fields any time theyβre focused, to draw attention to the fact that keyboard input will affect their contents.
#1.2 Focus across browsers
Some browsers do not support :focus-visible
yet (eg Safari). So, for full support we need the polyfill focus-visible.js instead.
<!-- Include the polyfill at the bottom of the page -->
<script src="../assets/polyfill-focus-visible.js"></script>
This polyfill adds the class .js-focus-visible
to the interactive element when
the focus should be visibile. We will use it instead of :focus-visible
selector.
/* Remove the outline for mouse users, once the JS is loaded */
.js-focus-visible button:focus {
outline: none;
}
/* Show the focus when interacted with keyboard */
.js-focus-visible button:focus.focus-visible {
outline: 3px solid tomato;
}
π― Goal: Refactor :focus-visible
to use focus-visible.js
instead.
π Tip: When using styles dependent on JS, take into account websites without JS. The prefix .js-focus-visible
ensures we only customize the focus if the polyfill is working, leaving the default focus as it is in case the JS doesn't load.
#2 Target size
Have you noticed how small some of the buttons are? These tiny elements can be frustrating specially in a mobile device.
Part of A11Y is to ensure people can easily interact with elements in multiple situations. WCAG contains 2 success criterion about this topic: WCAG 2.5.5 and the new WCAG 2.5.8 (draft). Even though, we can look at accessibility beyond guidelines.
π― Goal: Using your best judgment, increase the target size of the interactive elements.
Some suggestions:
- Main button: Increase size to comply with WCAG 2.5.5
- "home" link: Add more words to increase its width
- Corner button: Increase size to comply with WCAG 2.5.8, regardless of where it's used.
#3 Styling based on child focus
Imagine a new design requirement to the input field:
On input focus, the text "Nickname" turns purple.
There's a CSS pseudo-selector that allow us to style an element when it contains a focused element. It's called :focus-within
π― Goal: Use :focus-within
to solve the new design requirement. This bonus can be solved without Javascript.
Further reading
- A complete guide to links and buttons
- A guide to design WCAG-compliant focus indicators
- The not focus-visible trick
focus-visible
MDN spec- Why input fields always have focus-visible
- Looking at WCAG 2.5.5 for Better Target Sizes
- Use CSS to lint invalid links
WCAG Success Criterion
- WCAG 2.1.1 Keyboard - Level A
- WCAG 2.4.7 Focus visible - Level AA
- WCAG 2.5.5 Target size - Level AAA
- WCAG 2.5.8 Target size minimum - Level AA (WCAG 2.2 (Draft)).
Exercise takeaways
(After the exercise) Reveal takeaways
- Always testing new user interfaces with keyboard only.
- Links are meant for navigation. Buttons for in-page actions.
- Include custom focus indicators with strong contrast in your interactive elements.
- Use
:focus-visible
and:focus-whitin
to enhance the keyboard navigation.