
Module 8: Accessibility · Lesson 5 of 7
Keyboard Accessibility in HTML: Focus, Tab and tabindex
All lessons in Module 8
Goal: Make every control reachable and usable with the keyboard alone.
Learn
Plenty of people never touch a mouse. They press Tab to move from control to control and Enter or Space to use one. Whichever element receives the keys has focus, usually shown with an outline. Leave that outline alone.
Real HTML controls handle the keyboard for free. Links with an href, <button> and form fields can all take focus, as the HTML standard's section on focus (opens in a new tab) defines.
Where it goes wrong:
- A
<div>or<span>made clickable can never be reached with Tab. Use<button>. - An
<a>withouthrefisn't a link at all, and it can't get focus. tabindex="1"or higher forces a custom Tab order that hops around the page. Don't use it.
Put a skip link first on the page so keyboard users can jump past the menu: <a href="#content">Skip to content</a>.
The short version
- Tab order follows the order of your HTML, so keep the source order and the visual order the same.
- Links go somewhere and a
<button>does something. Both work with the keyboard for free. tabindex="0"adds an element to the natural Tab order andtabindex="-1"lets only scripts focus it. Stay away from positive values.- Keep the focus indicator visible. Restyle it as you like, but never remove it.
Example
<a href="#content">Skip to content</a>
<nav>
<a href="index.html">Home</a>
<a href="shop.html">Shop</a>
</nav>
<main id="content">
<h1>Welcome</h1>
<button type="button">Add to cart</button>
</main>Your task
Click inside the preview and press Tab a few times. Focus hops around and misses the two buttons that sell records. Fix the shop:
- Add a skip link as the very first element:
<a href="#content">Skip to content</a>. - Give the Home link an
href, for exampleindex.html. - Remove the
tabindexattributes from the Shop and About links. - Turn the Add to cart div and the Show reviews span into real
<button>elements.
Ctrl+Enter checks your code. Try Visual edit to change the page directly, DOM tree to see how the browser reads it, and Outline to hear it like a screen reader.
Quick quiz
Common mistakes
Wrong
button:focus {
outline: none;
}Right
button:focus-visible {
outline: 3px solid #1a5fb4;
outline-offset: 2px;
}With no outline, keyboard users can't see where they are, while :focus-visible styles focus only when the keyboard is in use.
Wrong
<a href="#" onclick="addToCart()">Add to cart</a>Right
<button type="button">Add to cart</button>An action dressed up as a link gets announced as a link, ignores Space, and sends you to the top of the page if the script fails.
Go deeper
Keyboard support carries a lot more than keyboards. Switch devices, sip-and-puff controls and many voice control tools work by sending keyboard-like commands. If a page works with Tab and Enter, it works for all of them.
WCAG 2.2 has four keyboard rules to know. Everything must be operable from a keyboard (2.1.1). Focus must never get trapped inside a widget (2.1.2). The focus order must make sense (2.4.3). And, new in 2.2, a focused element must not be completely hidden behind something like a sticky header or cookie banner (2.4.11, Focus Not Obscured (opens in a new tab)).
Native HTML saves you plenty of work here. <details> with <summary> gives you a show/hide section that already works with the keyboard, and a <dialog> opened as a modal keeps focus inside it. Neither needs custom key handling. The details element reference shows the full syntax.
Skip links are often hidden visually and revealed only when they receive focus. Keyboard users see them, and the design stays untouched. Pair them with the landmarks from the earlier lesson.
Once a week, put your mouse in a drawer and finish one real task on your site, signing up or checking out, with the keyboard alone.
Frequently asked questions
What does tabindex do in HTML?
tabindex decides whether an element can receive keyboard focus. tabindex="0" puts the element in the normal Tab order, at the spot where it sits in the HTML. tabindex="-1" takes it out of the Tab order but still lets scripts focus it, handy for a heading that a skip link jumps to. Positive values like tabindex="1" force a custom order, and that nearly always confuses people.
How do I test my website with a keyboard?
Click the address bar, then keep pressing Tab. Every link, button and field should be reached, in a sensible order, and you should always see where focus is. Press Enter on links and buttons, Space on buttons and checkboxes, arrow keys in radio groups and selects, and Shift+Tab to go back. Got stuck somewhere, or lost the focus outline? That's a bug.
Why should I not remove the focus outline?
Because the outline is the keyboard user's mouse pointer. Without it they can't tell which control will react to Enter. WCAG 2.2 requires a visible focus indicator (success criterion 2.4.7, Focus Visible (opens in a new tab)). If the default ring clashes with your design, restyle it with :focus-visible, using a strong color and a thicker line. Don't hide it.
