0Pricing
HTML Academy · Lesson

tabindex and accesskey

Control keyboard navigation order and shortcuts.

tabindex and accesskey is a free HTML Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Keyboard Navigation

Users without mice rely on Tab to navigate interactive elements:

  • Naturally focusable: <a href>, <button>, <input>, <select>, <textarea>
  • Non-interactive elements (<div>, <span>) are not in the tab order
  • tabindex controls whether and where an element appears in the tab order

tabindex="0"

tabindex="0" adds a non-interactive element to the natural tab order:

<div tabindex="0" role="button" onclick="handleClick()">
  Custom Button
</div>
<!-- Now Tab navigates to this div -->
<!-- It receives focus at the natural position in the DOM -->

<!-- Better: use a real button instead! -->
<button onclick="handleClick()">Real Button</button>

tabindex="-1"

tabindex="-1" makes an element programmatically focusable but removes it from the tab order:

<div id="modal" tabindex="-1" role="dialog">
  <!-- modal content -->
</div>

<script>
// Open modal and send focus to it:
document.getElementById('modal').focus();
// Modal is now focused but not in the normal tab sequence
</script>

tabindex Positive Values — Avoid

Positive tabindex values (e.g. tabindex="3") set a custom tab order — avoid this:

<!-- BAD: positive tabindex creates unpredictable order -->
<input tabindex="3">
<input tabindex="1">
<input tabindex="2">

<!-- The tab order becomes: 1, 2, 3, then all tabindex=0 elements -->
<!-- This almost always confuses users and fails WCAG 2.4.3 -->

<!-- Fix the DOM order instead of using positive tabindex -->

Focus Management in SPAs

Single-page apps must manage focus manually:

// When navigating to a new route:
document.querySelector('#main-content').focus();

// When opening a modal:
const modal = document.getElementById('modal');
modal.removeAttribute('hidden');
modal.querySelector('[autofocus], button, [tabindex]').focus();

// When closing a modal: return focus to the trigger
document.getElementById('open-btn').focus();

Focus Trap in Modals

Trap focus inside an open modal so Tab stays within it:

function trapFocus(element) {
  const focusable = element.querySelectorAll(
    'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
  );
  const first = focusable[0];
  const last = focusable[focusable.length - 1];

  element.addEventListener('keydown', e => {
    if (e.key === 'Tab') {
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault(); last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault(); first.focus();
      }
    }
  });
}

The accesskey Attribute

The accesskey attribute assigns a keyboard shortcut to an element:

<button accesskey="s">Submit</button>
<!-- On Windows: Alt+S focuses/activates the button -->
<!-- On Mac: Control+Option+S -->
<!-- On Firefox: Shift+Alt+S -->

<a href="/" accesskey="h">Home</a>

accesskey Limitations

accesskey has significant problems:

  • Activation keys vary across browsers and operating systems
  • Conflicts with browser shortcuts (e.g. Alt+F = File menu)
  • Not announced by screen readers by default
  • Rarely used in practice — document them if you do use them

Visible Focus Indicators

Never hide focus outlines — they are essential for keyboard users:

/* BAD: removes focus outline for everyone */
* { outline: none; }

/* Better: style focus outlines, don't remove them */
:focus-visible {
  outline: 2px solid #0070f3;
  outline-offset: 2px;
  border-radius: 3px;
}

/* :focus-visible only shows outline for keyboard navigation -->
/* Mouse clicks do not trigger :focus-visible in modern browsers */

Skip Link Pattern

A skip link lets keyboard users jump past repetitive navigation:

<a href="#main-content" class="skip-link">Skip to main content</a>

<nav>... long navigation ...</nav>

<main id="main-content" tabindex="-1">... content ...</main>

<!-- CSS: -->
<!--
.skip-link {
  position: absolute;
  top: -100%;
}
.skip-link:focus {
  top: 0;
}
-->

autofocus Attribute

The autofocus attribute moves focus to an element when the page loads:

<input type="search" autofocus placeholder="Search...">
<!-- Useful on search pages or forms with a single primary field -->
<!-- Use sparingly: it can disrupt users who rely on the page top for orientation -->
<!-- Only one element per page should have autofocus -->

Quick Check

Which tabindex value makes an element focusable via JavaScript but skips it in normal Tab navigation?

Recap: tabindex and accesskey

Keyboard accessibility essentials:

  • tabindex="0" — add to natural tab order
  • tabindex="-1" — programmatically focusable, not in tab order
  • Avoid positive tabindex values
  • Never remove :focus-visible outlines
  • Implement skip links for keyboard users
  • accesskey is available but rarely practical due to conflicts

Frequently asked questions

Is the “tabindex and accesskey” lesson free?

Yes — the full text of “tabindex and accesskey” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.

What will I learn in “tabindex and accesskey”?

Control keyboard navigation order and shortcuts. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start HTML Academy?

No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “tabindex and accesskey” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this HTML Academy lesson?

Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. id class style and title
  2. The hidden Attribute
  3. tabindex and accesskey
  4. Custom Data Attributes data-*
← Back to HTML Academy