Frontend engineer path · The browser · Topic 10 of 17

Accessibility essentials

Not started

Assistive technology doesn't see your pixels. It reads the accessibility tree the browser builds from your HTML: for each element a role (button, link, heading), a name, and a state (checked, expanded, disabled). Good semantics fill that tree in for free; a keyboard, a visible focus ring and enough contrast cover most of the rest. WCAG 2.2 is the standard that turns this into testable rules.

Why it matters: A page that works with a keyboard and a screen reader works for more people, ranks and tests better, and is a legal requirement in many places.

  1. 1Native elements first

    A <button> is focusable, clickable with Enter and Space, and announced as a button. A <div> with a click handler is none of these until you rebuild them all.

  2. 2Every control needs a name

    Assistive technology announces a role and an accessible name: the label, the button text, or aria-label when there is no visible text.

  3. 3Focus is the keyboard's cursor

    Everything clickable must be reachable with Tab, in a sensible order, with a visible focus indicator that isn't hidden behind sticky headers.

  4. 4AA is the usual target

    WCAG 2.2 has three levels, A, AA and AAA. Laws and contracts usually ask for AA, which includes 4.5:1 contrast for normal text.

1

How it works

The explanation, with examples you can run.

Semantic HTML does most of the work

Use the element that means what you want: <button> for actions, <a href> for navigation, <h1> to <h6> in order for structure, <nav>, <main> and <footer> as landmarks that screen reader users jump between, <label for> tied to every input, and <table> with <th> for tabular data. Native controls bring their keyboard behaviour, focusability and role with them.

ARIA is for the gaps: widgets HTML has no element for (tabs, a combobox), or state that changes (aria-expanded, aria-live for status messages). The first rule of ARIA is not to use it when a native element will do, because role="button" only changes the announcement; you still have to add tabindex="0" and the key handling yourself. The ARIA Authoring Practices Guide shows the expected keyboard pattern for each widget.

Names, images and forms

Every interactive element needs an accessible name. A button's text is its name; an icon-only button needs aria-label or visually hidden text. Informative images need alt text that says what the image tells you; decorative ones get alt="" so they are skipped. Errors in forms should be in text, linked to the field with aria-describedby, not only shown in red.

Focus

Tab order follows the DOM order, so keep the DOM in reading order and avoid positive tabindex values. Never remove the focus outline without replacing it; :focus-visible lets you show it for keyboard users only. When a dialog opens, move focus into it and return it to the trigger when it closes (the <dialog> element's showModal() handles much of this).

Contrast and WCAG levels

WCAG success criteria are graded A (the minimum), AA and AAA. AA is what most laws and policies reference, and WCAG 2.2, first published as a W3C Recommendation in October 2023, is the current version. It added nine criteria, including visible focus not hidden by sticky content, minimum target sizes and logins that don't depend on memorising or solving something. It also made 4.1.1 Parsing obsolete.

Contrast is computed from the relative luminance of the two colours. This is the formula from the WCAG 2.2 definitions:

⌘/Ctrl + Enter
OutputNot run yet

Press Run to see what your code prints, in order.

Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.

Automated checkers catch only part of the real problems. Also try the page with only a keyboard, at 200% zoom, and with a screen reader (VoiceOver on macOS and iOS, NVDA on Windows, TalkBack on Android).

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.What is missing from this control for a keyboard user?
    <div class="btn" onclick="save()">Save</div>
  2. 2.Grey text #777777 on white has a contrast ratio of about 4.48:1. Does it meet WCAG 2.2 AA for body text?
  3. 3.Which of these is new in WCAG 2.2 at level AA?

0 of 3 right so far. Get all three to finish this topic.