- name
- accessibility-review
- description
- Conducts a WCAG 2.1 AA accessibility review covering color contrast, keyboard navigation, screen reader markup, touch targets, and ARIA labels with a structured remediation checklist.
Use when the user asks to review accessibility, check WCAG compliance, audit for screen reader compatibility, or evaluate keyboard navigation.
Do NOT use for general UX audits (use ux-audit), visual hierarchy critique (use visual-hierarchy-review), or responsive layout testing (use responsive-layout-design).
- license
- Apache-2.0
- metadata
- {"author":"foundry-skills","version":"1.0.0","tags":"accessibility design checklist","category":"design-creative","subcategory":"ui-ux-design","depends":"","disclaimer":"none","difficulty":"intermediate"}
# Accessibility Review
## When to Use
**Use this skill when:**
- The user asks for a WCAG 2.1 AA (or AAA) compliance review of a specific interface, page, or component
- The user wants to audit color contrast ratios, keyboard navigation flows, or screen reader markup on a design mockup or live interface
- The user needs a structured remediation checklist before handing a design off to developers or before a product launch
- The user asks how to make a specific interface element -- modal dialog, data table, custom dropdown, date picker, carousel -- accessible
- The user wants to evaluate touch target sizes, gesture alternatives, or mobile accessibility for an iOS or Android interface
- The user needs to assess form accessibility including label associations, error identification, and autocomplete attributes
- The user wants to validate ARIA usage on a component and confirm roles, states, and properties are correctly applied
- The user describes an accessibility complaint received from a user with a disability or a result from an automated accessibility scan and wants to understand severity and remediation
**Do NOT use when:**
- The user wants a general usability audit covering task completion, information architecture, or cognitive load beyond disability-specific concerns -- use `ux-audit`
- The user wants to critique visual hierarchy, typography scale, or design aesthetics -- use `visual-hierarchy-review`
- The user wants to design or test responsive breakpoints and fluid layouts -- use `responsive-layout-design`
- The user wants to write the actual accessible HTML, CSS, or JavaScript implementation -- use a software-development skill for that implementation work; this skill covers the review and specification of what needs to be implemented
- The user wants to conduct user research with participants who have disabilities -- this requires participant recruitment, consent protocols, and research methodology beyond an audit
- The user wants a legal compliance opinion on whether an interface meets ADA, Section 508, or EN 301 549 requirements -- recommend consulting a qualified accessibility attorney or certified auditor for legal opinions
---
## Process
### Step 1 -- Gather Context and Scope the Review
Before evaluating anything, establish what you are reviewing and at what fidelity. Ask or infer:
- **Interface type:** Web page (document vs. web app), native mobile app (iOS/Android), desktop application, PDF document, or design mockup (static image, Figma/Sketch spec, wireframe)
- **Target conformance level:** Default to WCAG 2.1 AA unless the user specifies AAA or a regulatory framework (Section 508 references WCAG 2.0 AA; EN 301 549 references WCAG 2.1 AA)
- **Component inventory:** What interactive components exist? Identify forms, modals, dropdowns, carousels, data tables, accordions, tabs, date pickers, rich text editors, media players, maps, and any custom widgets
- **User population considerations:** Any specific disability groups to prioritize -- low vision users (contrast, zoom), blind users (screen reader), motor impairment (keyboard only, switch access), cognitive disabilities (plain language, error prevention), deaf or hard of hearing (captions, transcripts)
- **Artifacts available:** Live URL, design file screenshots, HTML source snippet, component specification, or verbal description. Note what cannot be evaluated without running code.
- **Existing findings:** Any prior audit results, automated scan reports (axe, Lighthouse, Deque), or user-reported issues that should anchor the review
If the user provides a verbal description only, state explicitly which findings are inferred from the description and which would require live testing to confirm.
---
### Step 2 -- Evaluate Perceivable Criteria (WCAG Principle 1)
Work through each sub-principle systematically. For each finding, record the criterion number, a specific finding, and a specific fix.
**1.1 -- Text Alternatives (SC 1.1.1)**
- Every non-text element (image, icon, chart, infographic, CAPTCHA, video thumbnail, decorative divider) needs a text alternative or must be explicitly marked decorative
- Decorative images: `alt=""` on `<img>` or `role="presentation"` / `aria-hidden="true"` on SVG and icon fonts
- Informative images: `alt` text that conveys the meaning, not just a file name or "image of..."
- Functional images (logo linked to home, icon button): `alt` text describes the function, not the appearance ("Return to homepage", not "Company logo")
- Complex images: charts and infographics need a short alt plus a long description -- either adjacent visible text, a `<figure>` with `<figcaption>`, or `aria-describedby` pointing to a descriptive paragraph. The description must convey the same data insight as the visual.
- Icon fonts (Font Awesome, Material Icons rendered via CSS): These are invisible to screen readers unless `aria-hidden="true"` is on the icon element and a visually hidden label is provided to the parent button/link
- Animated GIFs that convey information need a text alternative; purely decorative animated GIFs should be `aria-hidden`
**1.3 -- Adaptable Structure (SC 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5)**
- Heading hierarchy must be logical and not skip levels (h1 -> h2 -> h3, never h1 -> h3). A page should have exactly one `<h1>`.
- Landmark regions must be present: `<header>`, `<nav>`, `<main>`, `<footer>`, and optionally `<aside>`, `<section>` (with accessible name). Every visible page region should map to a landmark.
- Lists of items must use `<ul>`, `<ol>`, or `<dl>` -- not manually typed bullets or numbers in a paragraph
- Data tables must use `<table>` with `<th>` for headers and `scope="col"` or `scope="row"` on header cells. Complex tables (multi-level headers) require `id`/`headers` attribute pairings.
- Reading order in the DOM must match visual reading order. If CSS positions content visually out of DOM order, screen readers and keyboard users will encounter a confusing sequence.
- Instructions must not rely solely on sensory characteristics: "click the red button" fails; "click the Submit button" passes. "The form is on the right" fails; "The form below the navigation" passes.
- SC 1.3.4 -- Orientation: Do not lock content to portrait or landscape unless essential (e.g., a piano app)
- SC 1.3.5 -- Identify Input Purpose: For inputs collecting personal data, add `autocomplete` attributes: `autocomplete="name"`, `autocomplete="email"`, `autocomplete="current-password"`, `autocomplete="new-password"`, `autocomplete="tel"`, `autocomplete="street-address"`, `autocomplete="postal-code"`, `autocomplete="cc-number"`, etc. This benefits users with cognitive disabilities and password managers.
**1.4 -- Distinguishable (SC 1.4.1 through 1.4.13)**
Color contrast is the most commonly failed criterion. Apply these exact thresholds:
| Text Type | Minimum (AA) | Enhanced (AAA) |
|---|---|---|
| Normal text (below 18px regular or 14px bold) | 4.5:1 | 7:1 |
| Large text (18px+ regular or 14px+ bold) | 3:1 | 4.5:1 |
| UI component boundaries, icons, focus indicators | 3:1 | N/A (AAA) |
| Inactive/disabled elements | Exempt | Exempt |
| Logo/brand elements | Exempt | Exempt |
- Always state contrast as a specific ratio (e.g., "2.7:1, fails the 4.5:1 AA minimum by 40%"). Never say "low contrast" without a number.
- Common contrast failures to check: placeholder text in inputs (almost always too light), hint/helper text, disabled-looking but actually active elements, ghost buttons with colored text on white, light gray text on white (#767676 is the lightest gray that passes 4.5:1 on white -- anything lighter fails)
- SC 1.4.1 -- Color alone: State indicators, error states, required field markers, and graph series must use more than color. Add an icon, pattern, text label, or border in addition to color.
- SC 1.4.4 -- Resize text: Text must be readable and functional at 200% browser zoom without horizontal scrolling at 320px viewport width (a proxy for SC 1.4.10 Reflow)
- SC 1.4.10 -- Reflow: At 320 CSS pixels wide, content must reflow to a single column without horizontal scroll. This tests zoom behavior on mobile.
- SC 1.4.11 -- Non-text contrast: The visible boundary of an input field, the track of a slider, the check of a checkbox (if custom-styled), and all meaningful icons must have 3:1 contrast against adjacent colors
- SC 1.4.12 -- Text spacing: Text must remain readable when line-height is set to 1.5x font size, letter-spacing 0.12em, word-spacing 0.16em, and paragraph spacing 2x font size -- without loss of content or functionality
- SC 1.4.13 -- Content on hover/focus: Tooltips and hover popups that appear on keyboard focus or mouse hover must be persistent (don't disappear when the mouse moves over them), dismissible (Escape key closes them without moving focus), and hoverable (the user can move the mouse onto the popup itself)
---
### Step 3 -- Evaluate Operable Criteria (WCAG Principle 2)
**2.1 -- Keyboard Accessible (SC 2.1.1, 2.1.2, 2.1.4)**
- The cardinal rule: every action achievable with a mouse must also be achievable with a keyboard alone
- Tab sequence test: Tab forward through all interactive elements, Shift+Tab backward. Verify every button, link, input, select, checkbox, and custom widget receives focus.
- Keyboard trap test: When focus enters a modal, datepicker, or third-party widget, can the user Tab out or press Escape to dismiss? A keyboard trap is a WCAG 2.1.2 critical failure.
- Custom widget keyboard patterns (ARIA Authoring Practices Guide patterns):
- **Menu/navigation:** Arrow keys move between items, Enter/Space activates, Escape closes, Tab moves out of menu
- **Tabs:** Arrow keys switch tabs, Tab moves to tab panel content
- **Accordion:** Enter/Space expands/collapses panel, arrow keys optionally move between headers
- **Dialog/modal:** Tab cycles within modal only, Escape closes, focus returns to trigger on close
- **Listbox/combobox:** Arrow keys navigate options, Enter selects, Escape closes dropdown, type-ahead filtering is expected
- **Date picker:** Arrow keys navigate days, Page Up/Down navigate months, Home/End jump to start/end of week
- **Carousel/slider:** Arrow keys move between slides, pause button stops autoplay
- SC 2.1.4 -- Character Key Shortcuts: If single-character keyboard shortcuts are implemented, they must be remappable, disableable, or only active on focus
**2.4 -- Navigable (SC 2.4.1 through 2.4.7)**
- SC 2.4.1 -- Skip links: A "Skip to main content" link must be the first focusable element on every page. It can be visually hidden until focused, but must become visible on focus and must work (actually move focus to `<main>` or the landmark).
- SC 2.4.2 -- Page titles: Format as "Page Name -- Site Name". Every page must have a unique title. Single-page apps must update `document.title` on route changes.
- SC 2.4.3 -- Focus order: The tab sequence must follow a logical reading flow. A common failure: modals that open at the bottom of the DOM while visually appearing in the center -- focus continues behind the modal overlay.
- SC 2.4.4 -- Link purpose: "Read more", "Click here", "Learn more", "Download" are failures when appearing multiple times on a page. Each link must be uniquely identifiable from its text or from its text plus programmatic context (the containing heading, list item, table cell, or `aria-label`/`aria-labelledby`).
- SC 2.4.6 -- Headings and labels: Headings must describe their section. Form labels must describe what the field collects, not just format ("Enter your 10-digit phone number" is better than "Phone").
- SC 2.4.7 -- Focus visible: The default browser focus ring must not be removed (`outline: none` or `outline: 0` without a replacement is a critical failure). Replacement focus indicators must meet 3:1 contrast against adjacent colors. WCAG 2.2 SC 2.4.11 (AA) strengthens this to require a minimum 2px perimeter with specified area -- consider flagging this as a forward-looking recommendation.
**2.5 -- Input Modalities (SC 2.5.1 through 2.5.4)**
- SC 2.5.1 -- Pointer gestures: Any functionality using a multipoint (pinch-to-zoom, two-finger swipe) or path-based gesture (swipe to delete, drag-and-drop) must also be operable with a single pointer (tap or click). Alternative: a button labeled "Delete" alongside swipe-to-delete.
- SC 2.5.2 -- Pointer cancellation: For single-pointer events, the action must be completable using the up-event (mouseup, touchend), not the down-event. This allows users to cancel accidentally initiated actions by dragging the pointer off the control before releasing.
- SC 2.5.3 -- Label in name: If a component has a visible text label, its accessible name (from `aria-label`, `aria-labelledby`, or `<label>`) must contain or start with that visible text. A button that says "Submit" must not have `aria-label="Send form"` -- voice control users say what they see.
- SC 2.5.4 -- Motion actuation: Functionality triggered by device motion (shake to undo, tilt to scroll) must have a UI alternative, and motion triggering must be disableable (for users who have involuntary movement).
---
### Step 4 -- Evaluate Understandable Criteria (WCAG Principle 3)
**3.1 -- Readable (SC 3.1.1, 3.1.2)**
- SC 3.1.1: The primary language of the page must be declared in the `<html lang="en">` attribute (or appropriate BCP 47 language code: `fr`, `es`, `zh-Hans`, `ar`, etc.)
- SC 3.1.2: Inline language changes must be marked with `lang` attributes on the specific element. A French phrase in an English page needs `<span lang="fr">...</span>` so screen readers switch pronunciation accordingly.
**3.2 -- Predictable (SC 3.2.1, 3.2.2, 3.2.3, 3.2.4)**
- SC 3.2.1 -- On focus: Receiving focus must not trigger a context change. A dropdown that auto-submits when an option is focused (not selected) fails.
- SC 3.2.2 -- On input: Changing an input value must not cause an unexpected context change. A search field that submits automatically after 3 characters without warning fails. Provide a submit button or warn the user.
- SC 3.2.3 -- Consistent navigation: Navigation menus must appear in the same order and position on every page of a site.
- SC 3.2.4 -- Consistent identification: If a component appears on multiple pages (search field, cart icon, user avatar menu), it must have the same accessible name everywhere.
**3.3 -- Input Assistance (SC 3.3.1 through 3.3.4)**
- SC 3.3.1 -- Error identification: When validation fails, identify the specific field(s) in error and describe what is wrong in text. "Invalid input" fails. "Email address must include an @ symbol" passes.
- SC 3.3.2 -- Labels or instructions: Required fields must be identified (asterisk must be explained before the form, e.g., "* indicates required"). Date formats must be specified inline or in a hint (MM/DD/YYYY vs. YYYY-MM-DD). Password requirements must be visible before submission, not only after an error.
- SC 3.3.3 -- Error suggestion: When a user makes a predictable error (wrong date format, email missing @, zip code wrong length), suggest the correct input format in the error message.
- SC 3.3.4 -- Error prevention: For submissions with legal, financial, health, or data-deletion consequences, provide at least one of: reversibility (undo option), opportunity to review and correct before finalizing, or a confirmation step.
---
### Step 5 -- Evaluate Robust Criteria (WCAG Principle 4)
**4.1 -- Compatible (SC 4.1.1, 4.1.2, 4.1.3)**
SC 4.1.1 (Parsing) is largely addressed by valid HTML, but several patterns still cause real-world screen reader failures:
- Duplicate `id` attributes: If two elements share an `id`, `aria-labelledby` and `<label for>` associations break
- Improperly nested elements: `<button>` inside `<a>`, `<div>` as direct child of `<ul>`, `<p>` wrapping block elements all cause parsing errors
- Unclosed tags or malformed attribute syntax cause assistive technology parsers to misinterpret the tree
SC 4.1.2 -- Name, Role, Value -- is the most technically demanding criterion:
- **Name:** Every interactive element must have an accessible name. Sources in priority order: `aria-labelledby` (references visible text) > `aria-label` (invisible string) > `<label>` (for form controls) > `alt` (for images) > `title` (fallback, not reliable) > element content (for buttons/links)
- **Role:** Native HTML elements carry implicit roles. Custom widgets built from `<div>` or `<span>` must have explicit ARIA roles: `role="button"`, `role="dialog"`, `role="tablist"`, `role="tab"`, `role="tabpanel"`, `role="menu"`, `role="menuitem"`, `role="combobox"`, `role="listbox"`, `role="option"`, `role="grid"`, etc.
- **Value/State:** Interactive elements must expose their current state: `aria-expanded="true/false"` (accordions, dropdowns), `aria-checked="true/false/mixed"` (checkboxes, toggle buttons), `aria-selected="true/false"` (tabs, options), `aria-pressed="true/false"` (toggle buttons), `aria-disabled="true"` (disabled controls that should remain focusable for discovery), `aria-invalid="true"` (fields in error), `aria-required="true"` (required fields, though native `required` attribute is preferred)
- **ARIA rules to enforce:** Never use `aria-label` on an element that already has a matching visible label -- this creates a conflict between what sighted users see and what screen reader users hear. Never use `role="presentation"` or `aria-hidden="true"` on a focusable element. Never place interactive elements inside an `aria-hidden="true"` container.
- SC 4.1.3 -- Status Messages: Messages that appear without a page reload and without receiving focus (success toasts, loading spinners, form error summaries, cart update notices) must be announced to screen readers using `role="status"` (polite), `role="alert"` (assertive, for errors), or `aria-live="polite"/"assertive"`. The live region container must be in the DOM before the message is injected into it.
---
### Step 6 -- Classify, Prioritize, and Assign Remediation Effort
For every finding, assign:
**Result classification:**
- **FAIL** -- Does not meet the applicable WCAG 2.1 AA success criterion. Must be remediated for compliance.
- **WARN** -- Technically passes the criterion but creates a demonstrably poor experience for users with disabilities. Strongly recommended to fix.
- **PASS** -- Meets the criterion.
- **N/A** -- The criterion does not apply (e.g., 1.2.1 Audio-only on a page with no audio content).
**Priority classification:**
- **P1 (Critical):** Blocks access completely -- keyboard trap, no accessible name on primary CTA, missing form labels, media with no alternative. Fix before release.
- **P2 (Serious):** Significantly degrades experience -- low contrast below 3:1, missing focus indicator, error messages not linked to fields. Fix in next sprint.
- **P3 (Moderate):** Creates friction but workaround exists -- missing autocomplete, non-descriptive link text that is still technically unique, small touch targets (30-43px). Fix in backlog.
- **P4 (Minor):** Best practice improvement -- inconsistent focus order that is logical but not optimal, redundant ARIA labels. Fix when convenient.
**Effort estimation:**
- **S (Small):** CSS-only change, single attribute addition -- under 1 hour developer time
- **M (Medium):** HTML restructuring, JavaScript state management, content rewrite -- 1-4 hours
Voir sur GitHub