What accessibility is and why it's non-negotiable
Accessibility means designing products that people with disabilities can perceive, understand, navigate, and interact with. This includes people who are blind, deaf, have motor impairments, cognitive disabilities, or temporary situational limitations like a broken arm or bright sunlight on a screen.
The case for accessibility is three-layered. First, it's an ethical obligation — excluding people from using your product is excluding them from participation. Second, it's often a legal requirement — the ADA, Section 508, the European Accessibility Act, and similar laws in dozens of countries mandate accessible digital products. Third, it makes your product better for everyone. Curb cuts were designed for wheelchairs but help parents with strollers, travelers with luggage, and delivery workers with carts. The same principle applies to digital design: captions help people in noisy environments, keyboard navigation helps power users, clear error messages help everyone.
The numbers
Approximately 16% of the global population lives with some form of disability. In many markets, that's a larger segment than any demographic you're deliberately designing for. And disability is not binary — it's a spectrum that includes permanent conditions (blindness), temporary conditions (broken wrist), and situational limitations (holding a baby). Design for the extremes and the middle benefits.
The four WCAG principles: POUR
The Web Content Accessibility Guidelines (WCAG) organize all requirements under four principles. Every accessibility decision maps to one of these.
POUR Framework Framework
Use this to structure any accessibility review or design decision.
Perceivable
Users must be able to perceive the information. If content is only visual, blind users can't access it. If it's only audio, deaf users can't access it. Provide alternatives: alt text for images, captions for video, text alternatives for icons.
Operable
Users must be able to operate the interface. If it requires a mouse, keyboard-only users are locked out. If it requires precise clicking, people with motor impairments struggle. Support keyboard navigation, provide adequate touch targets, don't rely on hover alone.
Understandable
Users must be able to understand the content and how the interface works. Use clear labels, predictable navigation, helpful error messages. Don't assume familiarity with jargon or conventions. Make the interface forgiving of mistakes.
Robust
Content must work across technologies — browsers, screen readers, magnifiers, voice control. Use semantic HTML, valid markup, and standard ARIA patterns. Don't build custom widgets that only work in one browser.
Perceivable: making content available to all senses
Alt Text Core Pattern
Use when: any image appears in your interface.
Every meaningful image needs alt text that conveys its purpose, not its appearance. A photo of a chart should describe what the chart shows, not "a bar chart." A decorative image gets an empty alt attribute (alt="") so screen readers skip it. Icons that function as buttons need alt text describing the action ("Close," "Search"), not the icon shape ("magnifying glass").
Color Contrast Core Pattern
Use when: choosing any text color, button color, or UI element color.
WCAG AA requires a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text (18px+ or 14px+ bold). For UI components and graphical objects, 3:1 against adjacent colors. Never use color alone to convey meaning — a red error state also needs an icon or text label. Tools: WebAIM Contrast Checker, browser DevTools accessibility panel, Figma plugins like Stark.
Captions and Transcripts Core Pattern
Use when: any audio or video content appears in your product.
Pre-recorded video needs synchronized captions. Live video needs real-time captions (auto-generated is acceptable as a starting point but should be reviewed). Audio-only content needs a text transcript. Captions should include speaker identification and relevant sound effects, not just dialogue.
Text Resize and Reflow Core Pattern
Use when: building any responsive layout.
Users must be able to resize text up to 200% without loss of content or functionality. Use relative units (rem, em) not fixed pixels for font sizes. At 320px viewport width (or 400% zoom), content should reflow into a single column with no horizontal scrolling. Test by zooming your browser to 200% and checking that nothing breaks.
Operable: keyboard, touch, and input methods
Keyboard Navigation Core Pattern
Use when: building any interactive element.
Every interactive element must be reachable and operable with keyboard alone. Tab moves forward, Shift+Tab moves backward, Enter/Space activates, Escape closes. The focus order must follow a logical reading sequence. Never remove the focus outline (outline: none) without providing a visible alternative. Custom components need explicit tabindex and keyboard event handlers.
Focus Management Core Pattern
Use when: modals, drawers, or dynamic content changes occur.
When a modal opens, focus must move into it. When it closes, focus returns to the trigger element. Tab must be trapped inside the modal — users shouldn't be able to tab to elements behind it. When new content loads dynamically (infinite scroll, AJAX updates), announce it to screen readers with ARIA live regions. Skip links at the top of the page let keyboard users jump past the navigation to the main content.
Touch Targets Core Pattern
Use when: designing for mobile or touch interfaces.
Minimum touch target size: 44×44px (WCAG) or 48×48dp (Material Design). Spacing between targets matters as much as size — adjacent targets that are too close cause mis-taps. Text links in paragraphs should have enough padding to be tappable. If a target must be smaller than 44px visually, extend the tappable area with invisible padding.
The keyboard test
Unplug your mouse and try to use your product with keyboard alone for 10 minutes. Can you reach every interactive element? Can you see where focus is? Can you operate menus, modals, and forms? Can you escape from everything? This single test catches more accessibility issues than any automated tool.
Understandable: clear labels, errors, and predictability
Form Labels and Instructions Core Pattern
Use when: building any form.
Every form input needs a visible label (not just placeholder text — placeholders disappear on focus). Labels must be programmatically associated with inputs using for/id or by wrapping the input in the label element. Required fields must be indicated before the user submits. Input format expectations (e.g., "MM/DD/YYYY") should be visible, not hidden in tooltips.
Error Messages Core Pattern
Use when: validating any user input.
Errors must identify what went wrong and how to fix it. "Invalid input" is useless. "Email address must include an @ symbol" is helpful. Errors must be visually connected to the field they relate to, announced to screen readers (use aria-describedby or aria-live), and not rely solely on color (add an icon or text prefix). Provide error summaries at the top of long forms.
Predictable Behavior Core Pattern
Use when: designing navigation, forms, or any repeated interaction.
Navigation should appear in the same location on every page. Similar components should behave consistently throughout the product. Changing a select dropdown should not automatically submit the form or navigate away — unexpected actions disorient users. If an action has significant consequences (deleting data, submitting a form), provide confirmation or undo.
Robust: semantic HTML and ARIA
Semantic HTML Core Pattern
Use when: writing any HTML.
Use native HTML elements for their intended purpose: <button> for actions, <a> for navigation, <nav> for navigation regions, <main> for primary content, <h1>–<h6> for heading hierarchy. Native elements come with built-in keyboard behavior, screen reader announcements, and platform integration. A <div onclick> is not a button — it lacks keyboard support, role announcement, and disabled state handling.
ARIA (Accessible Rich Internet Applications) Core Pattern
Use when: native HTML elements aren't sufficient for your component.
ARIA adds accessibility information to custom components. The five rules: (1) Use native HTML first — ARIA is a last resort. (2) Don't change native semantics unless you must (<h2 role="tab"> is usually wrong). (3) All interactive ARIA controls must be keyboard operable. (4) Don't use role="presentation" or aria-hidden="true" on focusable elements. (5) All interactive elements must have an accessible name. Common ARIA patterns: tabs (role="tablist"), accordions (aria-expanded), alerts (role="alert"), dialogs (role="dialog").
The first rule of ARIA
Don't use ARIA if you can use native HTML. A <button> is always better than <div role="button" tabindex="0">. ARIA doesn't add behavior — it only adds metadata. You still need to implement keyboard handlers, focus management, and state changes yourself. Bad ARIA is worse than no ARIA because it creates false expectations for assistive technology users.
Testing with assistive technology
Screen Reader Testing Technique
Use when: validating that your product works for blind and low-vision users.
Test with at least one screen reader: VoiceOver on Mac/iOS (built-in, activate with Cmd+F5), NVDA on Windows (free download), or TalkBack on Android (built-in). Navigate your product using only screen reader commands. Check: Are images announced with meaningful alt text? Do form labels read correctly? Do headings create a navigable structure? Are dynamic updates (notifications, loading states) announced? Can you complete core tasks without seeing the screen?
Automated Testing Tools Tool
Use when: building an accessibility testing workflow.
Automated tools catch about 30-40% of accessibility issues — primarily technical ones like missing alt text, insufficient contrast, and invalid ARIA. Use axe DevTools (browser extension), Lighthouse (built into Chrome DevTools), or WAVE (web-based). Run these on every page and component. But remember: automated tools cannot test whether alt text is meaningful, whether focus order is logical, or whether the experience actually makes sense to an assistive technology user. Manual testing is essential.
Keyboard-Only Testing Technique
Use when: doing any accessibility review.
Disconnect your mouse. Navigate your entire product with Tab, Shift+Tab, Enter, Space, Escape, and arrow keys. Verify: Can you reach every interactive element? Is focus always visible? Does the focus order make sense? Can you open and close modals, menus, and dropdowns? Can you complete every user flow? This is the single highest-value accessibility test you can run.
Accessibility engineering communication
Accessibility Requirements Handoff Framework
Use when: handing off designs to engineers and need to specify accessibility behavior that isn't visible in mockups.
Most accessibility problems come from the gap between what designers envision and what engineers implement — because accessibility behavior is invisible in static mockups. Bridge this gap with explicit specs. ARIA patterns brief: For every custom component (dropdown, modal, accordion, tab panel), document which ARIA role, states, and properties to use. Don't make engineers guess — specify "this dropdown uses role='listbox' with aria-activedescendant for focus management" rather than "make this accessible." Keyboard navigation specs: For each interactive component, document the expected keyboard behavior: which keys do what, tab order, focus trapping for modals, arrow key navigation within composite widgets. Include a keyboard behavior table in your design specs. Accessible name specifications: For every interactive element, define the accessible name — the text that screen readers announce. This includes icon-only buttons (what does the screen reader say?), images (alt text or decorative?), and form fields (visible label or aria-label?). Include these annotations directly on your design files.
Cognitive accessibility across age groups
Cognitive Accessibility Framework Framework
Use when: designing for audiences with varying cognitive abilities — young users, older adults, users with cognitive disabilities, or varying literacy levels.
Cognitive accessibility extends beyond screen readers and keyboard navigation into how well an interface supports thinking, remembering, and deciding. For young users: Minimize reliance on reading — use visual cues, icons, and spatial memory. Simplify decision trees. Provide clear undo paths because young users explore unpredictably. Avoid time pressure. For older adults: Increase touch target sizes beyond WCAG minimums (target 48px minimum, ideally 56px). Use higher contrast ratios. Reduce reliance on short-term memory — keep related information visible rather than requiring users to remember across screens. Allow more time for task completion. Avoid hover-dependent interactions. For varying literacy levels: Use plain language (aim for a 6th–8th grade reading level for general audiences). Break complex processes into simple, clearly labeled steps. Use concrete language over abstractions. Provide examples alongside instructions. For users with cognitive disabilities: Minimize distractions (reduce animation, avoid autoplay, provide focus modes). Support consistent navigation patterns. Use familiar interface conventions rather than novel interactions. Provide clear error recovery without requiring users to remember what went wrong.
Templates and checklists
[Name of the page or component being reviewed]
[Alt text present? Contrast ratios passing? Color not sole indicator? Text resizable?]
[Keyboard navigable? Focus visible? Touch targets ≥44px? No keyboard traps?]
[Labels on all inputs? Error messages helpful? Behavior predictable?]
[Semantic HTML? Valid ARIA? Screen reader tested?]
- All images have meaningful alt text (or empty alt for decorative images)
- Color contrast ratios meet WCAG AA (4.5:1 text, 3:1 large text and UI)
- Information is not conveyed by color alone
- All interactive elements are keyboard accessible
- Focus indicator is visible on every focusable element
- Focus order follows a logical reading sequence
- Touch targets are at least 44×44px
- All form inputs have visible, associated labels
- Error messages identify the problem and suggest a fix
- Heading hierarchy is logical (no skipped levels)
- Page has a single h1 and uses landmarks (main, nav, footer)
- Skip link present to bypass navigation
- Modals trap focus and return focus on close
- Dynamic content changes announced via ARIA live regions
- Text resizes to 200% without loss of content
- Tested with at least one screen reader
Real-world examples
Case study
GOV.UK: accessibility as a design principle
The UK Government Digital Service built accessibility into every layer of their design system. Every component in the GOV.UK Design System is tested with screen readers, keyboard navigation, and high magnification before release. Their approach: start with semantic HTML, layer on progressive enhancement, and test with real assistive technology users. The result is one of the most accessible government services in the world — and also one of the simplest and most usable for everyone.
Why it works: Accessibility isn't a separate workstream — it's embedded in every component, every review, and every release criterion. The design system enforces it by default.
Case study
Microsoft Inclusive Design: the persona spectrum
Microsoft's Inclusive Design methodology reframes disability as a spectrum: permanent (one arm), temporary (arm in a cast), and situational (holding a baby). This insight shifted their design approach from "accommodate a small group" to "design for the extremes and everyone benefits." Their Xbox Adaptive Controller emerged from this thinking — a game controller designed for players with limited mobility that became a platform for customization that benefits all users.
Why it works: By broadening the definition of who benefits from accessible design, the team built organizational buy-in beyond compliance.
Case study
Target.com lawsuit: the cost of ignoring accessibility
In 2006, the National Federation of the Blind sued Target because their website was unusable with screen readers — images lacked alt text, forms lacked labels, and the checkout flow required a mouse. Target settled for $6 million and agreed to make their website fully accessible. The case established that the ADA applies to commercial websites and triggered an industry-wide shift toward digital accessibility compliance.
Why it works as a cautionary tale: The cost of retrofitting accessibility is always higher than building it in from the start. Legal risk is real, but the deeper lesson is that Target's checkout flow was bad for everyone — the inaccessible patterns also created friction for users without disabilities.
Common pitfalls
Treating accessibility as a checklist to pass, not a practice to maintain
Teams often audit once, fix the flagged issues, and move on. But accessibility breaks with every new feature, design change, and content update. It needs to be part of the continuous development process — in component libraries, code reviews, and QA workflows — not a one-time project.
Relying only on automated testing
Tools like axe and Lighthouse catch roughly 30-40% of WCAG issues. They can verify contrast ratios and missing alt text, but they can't assess whether alt text is meaningful, whether focus order is logical, or whether a screen reader user can actually complete a task. Automated tools are the starting point, not the finish line.
Hiding accessible alternatives instead of fixing the main experience
Building a separate "accessible version" of your site creates a second-class experience that's harder to maintain and inevitably falls out of sync. The main product should be accessible. If a component can't be made accessible, that's a signal to redesign the component, not to build a parallel version.
Removing focus outlines for aesthetics
outline: none on focusable elements makes your product unusable for keyboard users. If the default browser outline doesn't match your design, replace it with a custom focus style — never remove it. A common pattern: :focus-visible shows the outline only for keyboard navigation, not mouse clicks.