Web Accessibility — Cheat Sheet

Tags: accessibility, a11y, wcag, aria, html, frontend

Level: intermediate

TL;DR: Web accessibility ensures digital products are usable by everyone, focusing on semantic HTML, keyboard operability, ARIA attributes, and WCAG compliance.

Key concepts

WCAG is structured around four principles: Perceivable, Operable, Understandable, and Robust (POUR).

Compliance levels in WCAG are A (essential), AA (standard industry target), and AAA (highest).

Semantic HTML elements (<main>, <nav>, <button>) provide built-in accessibility roles, states, and keyboard support.

Color contrast requires a minimum ratio of 4.5:1 for normal text and 3:1 for large text under AA standards.

All interactive controls must be reachable and operable using only the keyboard.

Screen readers rely on the accessibility tree constructed by the browser from the DOM.

The first rule of ARIA: do not use ARIA when native HTML elements can fulfill the semantics.

Accessible names for interactive elements are derived from text content, aria-label, or aria-labelledby.

Visible focus rings must always be preserved for keyboard navigators.

Dynamic layout updates and asynchronous content shifts must notify assistive technology using ARIA live regions.

Typical questions and ready answers

Q: How do you approach accessibility when building a new user interface?R: I start with native semantic HTML to ensure baseline accessibility and keyboard support out of the box. Then I verify contrast ratios, manage focus traps in modals, and only introduce ARIA when custom interactive widgets strictly require it.

Q: What is the difference between aria-label, aria-labelledby, and aria-describedby?R: aria-label defines an explicit string name directly on the element. aria-labelledby points to an existing DOM element ID that acts as the accessible name, while aria-describedby points to secondary descriptive text read after the name.

Q: Why should you avoid outline: none in CSS?R: Removing focus outlines breaks keyboard navigation by making it impossible for sighted keyboard users to track where they are. If custom styling is needed, I replace the default outline with a custom, high-contrast :focus-visible ring.

Pitfalls and common mistakes

Using non-interactive elements like <div> or <span> with click handlers instead of real <button> elements.

Setting outline: none or outline: 0 without providing an accessible alternative for :focus-visible.

Overusing ARIA attributes or applying invalid ARIA roles that override correct native element semantics.

Forgetting alt attributes on <img> tags, or writing redundant text like "image of" inside alt.

Relying exclusively on color changes to convey status, errors, or required field states.

Hiding content visually with CSS (display: none or visibility: hidden) when it should remain audible to screen readers.

Trapping keyboard users inside open modals by failing to restrict tab order or missing an escape key handler.

Snippets and commands

<!-- Accessible icon button with text fallback -->
<button type="button" aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false" width="16" height="16">
    <path d="M1 1l14 14M15 1L1 15" />
  </svg>
</button>

HTML

<!-- Screen reader only utility class pattern -->
<style>
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
</style>
<span class="sr-only">Notifications (3 unread)</span>

HTML

<!-- Form control correctly associated with label and error message -->
<label for="user-email">Email address</label>
<input
  id="user-email"
  name="email"
  type="email"
  aria-invalid="true"
  aria-describedby="email-error"
/>
<span id="email-error" role="alert">Please enter a valid email address.</span>

CSS

/* Maintain clear focus indication for keyboard users only */
:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}

To review

[ ] Keyboard focus trap implementation patterns in vanilla TypeScript

[ ] Proper roles and states for combobox and tabs widgets under WAI-ARIA authoring practices

[ ] Automated accessibility testing via axe-core in Playwright or Jest

[x] Baseline semantic tags and heading hierarchy (h1 through h6)

[x] WCAG AA contrast ratio thresholds for text and graphical controls

References

W3C Web Content Accessibility Guidelines (WCAG) 2.2

WAI-ARIA Authoring Practices Guide (APG)

MDN Web Docs: Accessibility

Jarvis Interviews
Jarvis