Accessibility Checker logoAccessibility Checker

Reusable code

Accessibility Snippets

Copy reusable HTML, React, and Tailwind snippets for accessible UI patterns.

SnippetsReactTailwindHTMLFormsModals

Foundation Snippets

Start with native HTML and add ARIA only when the component needs extra relationships or state.

Skip link

Place this as the first focusable item in the page.

<a href="#main-content" class="sr-only focus:not-sr-only">
  Skip to main content
</a>
<main id="main-content">
  Page content
</main>

Accessible icon button

Use visible text when possible. For icon-only controls, provide a clear aria-label.

<button type="button" aria-label="Delete report" className="focus-ring rounded p-2">
  <TrashIcon aria-hidden="true" />
</button>

Current page nav link

Use aria-current for the active page in a navigation set.

<nav aria-label="Primary navigation">
  <a href="/">Home</a>
  <a href="/dashboard" aria-current="page">Dashboard</a>
</nav>

Forms and Errors

Accessible forms need visible labels, helpful instructions, specific errors, and predictable focus behavior.

Accessible form field with error

Connect labels, help text, and errors with id/htmlFor/aria-describedby.

<label htmlFor="email">Email</label>
<input
  id="email"
  type="email"
  aria-invalid={hasError}
  aria-describedby={hasError ? "email-error" : "email-help"}
/>
<p id="email-help">Use your work email address.</p>
{hasError ? <p id="email-error">Enter a valid email address.</p> : null}

Error summary

Move focus to the summary after submit only when validation fails.

<div role="alert" tabindex="-1" aria-labelledby="form-errors-title">
  <h2 id="form-errors-title">Fix these errors</h2>
  <ul>
    <li><a href="#email">Enter a valid email address.</a></li>
    <li><a href="#password">Password must be at least 8 characters.</a></li>
  </ul>
</div>

Required field

Use visible text and native required when the field is truly required.

<label for="name">Name <span aria-hidden="true">*</span></label>
<input id="name" name="name" required aria-describedby="name-required">
<p id="name-required">Required field.</p>

Interactive Components

These snippets show structure. Production components still need focus management and keyboard tests.

Accessible modal structure

Add focus trap, Escape close, background inert behavior, and focus return in the component.

<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Export report</h2>
  <p>Choose a format for your accessibility report.</p>
  <button type="button">Export PDF</button>
  <button type="button" aria-label="Close export dialog">Close</button>
</div>

Accordion section

A real button controls one panel and exposes expanded state.

<h3>
  <button type="button" aria-expanded={open} aria-controls="panel-keyboard">
    Keyboard testing
  </button>
</h3>
<div id="panel-keyboard" hidden={!open}>
  Keyboard testing content.
</div>

Toast alert

Use status for non-urgent updates and alert for urgent errors.

<div role="status" aria-live="polite" className="rounded border p-4">
  Report copied to clipboard.
</div>

Tabs shell

Add arrow-key handling and keep aria-selected synchronized with the active panel.

<div role="tablist" aria-label="Accessibility topics">
  <button role="tab" aria-selected="true" aria-controls="panel-wcag" id="tab-wcag">
    WCAG
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-aria" id="tab-aria">
    ARIA
  </button>
</div>
<section id="panel-wcag" role="tabpanel" aria-labelledby="tab-wcag">WCAG content</section>
<section id="panel-aria" role="tabpanel" aria-labelledby="tab-aria" hidden>ARIA content</section>

Tables and Responsive Content

Tables and scrollable regions need semantics, labels, and keyboard access.

Accessible table

Use captions and header cells so data relationships are clear.

<table>
  <caption>Monthly scan usage</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Scans</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">June</th>
      <td>42</td>
    </tr>
  </tbody>
</table>

Keyboard reachable scroll region

Use tabindex only when the region itself needs keyboard scrolling.

<div tabindex="0" role="region" aria-label="Transaction history" class="max-h-80 overflow-y-auto">
  Long scrollable content
</div>

Responsive code block

Make long code keyboard-scrollable and give it context.

<pre tabindex="0" aria-label="HTML example" class="overflow-x-auto">
  <code>&lt;button type="button"&gt;Save&lt;/button&gt;</code>
</pre>