Accessibility: Not Optional, Not Hard
1 in 4 adults in the US has a disability. Accessibility isn't a nice-to-have — it's a legal requirement (ADA, WCAG) and a market of over 1 billion people worldwide. The good news: most accessibility fixes are simple HTML changes.
The Quick Wins
<!-- 1. Use semantic HTML (not div for everything) -->
<nav>...</nav>
<main>...</main>
<article>...</article>
<aside>...</aside>
<footer>...</footer>
<button>Click me</button> <!-- NOT <div onclick> -->
<!-- 2. Always add alt text to images -->
<img src="chart.png" alt="Monthly revenue chart showing 20% growth" />
<img src="decorative-line.svg" alt="" /> <!-- empty alt for decorative -->
<!-- 3. Label form inputs -->
<label for="email">Email</label>
<input id="email" type="email" />
<!-- 4. Use headings in order -->
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<!-- Never skip levels (h1 → h3) -->Keyboard Navigation
/* Make focus visible (never remove outline without replacement) */
:focus-visible {
outline: 2px solid #4A90D9;
outline-offset: 2px;
}
/* DON'T do this */
:focus { outline: none; } /* makes keyboard nav impossible */- All interactive elements must be reachable with Tab
- Tab order should follow visual order
- Escape should close modals/dropdowns
- Enter/Space should activate buttons
- Arrow keys should navigate within components (tabs, menus)
Color Contrast
| Level | Normal Text | Large Text (18px+ or 14px+ bold) |
|---|---|---|
| AA (minimum) | 4.5:1 ratio | 3:1 ratio |
| AAA (enhanced) | 7:1 ratio | 4.5:1 ratio |
- Don't convey information with color alone (add icons, patterns, text)
- Test with color blindness simulators
ARIA (When HTML Isn't Enough)
<!-- Custom toggle button -->
<button aria-pressed="true">Dark Mode</button>
<!-- Loading state -->
<div aria-busy="true" aria-live="polite">Loading...</div>
<!-- Expandable section -->
<button aria-expanded="false" aria-controls="details">Show Details</button>
<div id="details" hidden>...</div>
<!-- Screen reader only text -->
<span class="sr-only">Close dialog</span>/* Screen reader only (visually hidden but accessible) */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}The #1 ARIA rule: No ARIA is better than bad ARIA. Use semantic HTML first. ARIA is for custom components that don't have native HTML equivalents.
Testing Checklist
- Navigate the entire page using only keyboard (Tab, Enter, Escape)
- Use a screen reader (VoiceOver on Mac, NVDA on Windows)
- Check color contrast with a tool (4.5:1 minimum)
- Run Lighthouse accessibility audit in Chrome DevTools
- Resize text to 200% — does layout still work?
- Test with browser zoom at 400%
Check your contrast: Color Contrast Checker — verify WCAG AA/AAA compliance for any color combination.