✎ Technique: Managing focus and inactive elements

Visually indicating which element has focus is important for effective keyboard navigation. It's also important to ensure that only those elements that are available visually for interaction are focusable. If an active element is intended to be unavailable in a particular state and it’s hidden from view, it should not be able to receive focus.

Having to tab through invisible controls to reach visible ones is arduous and potentially confusing for sighted users navigating the page by keyboard. Also, screen-reader users will hear the presence of controls that are intended to be hidden from use.

Examples

✓ Good example

In this example, an undisclosed submenu is hidden using display:none. Any children of elements with display:none are unfocusable, meaning that the invisible menu items are not in the focus order. This is correct.


<a href="#" aria-haspopup="true" role="button" aria-expanded="false">Good example</a>
<ul aria-label="submenu" style="display:none">
  <li><a href="#">News</a></li><!-- not focusable -->
  <li><a href="#">Contact Us</a></li>
</ul>

When the user clicks the aria-haspopup="true" link, JavaScript should reveal the submenu by setting its display value to block. This both reveals the menu visually and makes its items focusable.


<a href="#" aria-haspopup="true" role="button" aria-expanded="true">Good example</a>
<ul aria-label="submenu" style="display:block">
  <li><a href="#">News</a></li> <!-- focusable -->
  <li><a href="#">Contact Us</a></li>
</ul>

✗ Bad example

Another way to hide the submenu from view would be to set height:0 and overflow:hidden. The hidden submenu's items would still be in the focus order, meaning that a user who’s navigating using their keyboard would be able to focus controls that are not intended to be available.


<a href="#" aria-haspopup="true" role="button" aria-expanded="false">Bad example</a>
<ul aria-label="submenu" style="height:0;overflow:hidden">
  <li><a href="#">News</a></li> <!-- focusable -->
  <li><a href="#">Contact Us</a></li>
</ul>

✓ Good example

One exception to the rule of not including hidden controls in focus order is elements that become visible once they’re focused, like skip links. Skip links are navigation aids that provide a means for keyboard users to bypass navigation bars and jump directly to main page content, making it easier to get to important content.

In such a case, one implementation is to have these links hidden from view by default but still included in the page’s focus order. When they receive focus, the link text (for example "Skip to main content") should become visible so that keyboard users are made aware of the presence of the link and can choose to follow it if they wish.

Video: Invisible submenus and focus with NVDA and Firefox

Code editor

There is a code editor available to explore good and bad focus treatment relating to inactive controls. Try moving focus through the menu structure using your TAB key to see how the good and bad examples compare.