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 and Firefox Notes:

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:

#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

WCAG Success Criterion

Exercise takeaways

(After the exercise) Reveal takeaways