A11ySidekick
Describe what's on your screen — its structure and UI elements — and A11ySidekick filters all 55 WCAG 2.2 AA criteria down to only the ones that apply. Every item is assigned to the team that owns it: Design, Design→Dev, Dev, or Content.
Build a focused checklist for one screen
Name the screen, mark its structure and UI elements, and A11ySidekick will assemble the WCAG 2.2 AA criteria that apply. The always-on criteria are included every time.
Design-owned criteria
These decisions live entirely in Figma. Resolve them before anything leaves the design phase — no spec or handoff note needed.
Use of Color
Never use color as the only way to communicate something. If you strip all color from your design, every piece of information should still be readable.
✓ Do
Pair color with an icon, label, pattern, or underline to convey meaning✗ Don't
Use a red border alone to indicate an error field — without a label or iconContrast (Minimum)
Text must have a contrast ratio of at least 4.5:1 against its background. Small text that's hard to read isn't just a style problem — it's a barrier.
✓ Do
Check every text color + background combination with a contrast checker before finalising✗ Don't
Use light grey body copy on a white background because it "looks clean"Large text (18pt regular or 14pt bold and above) only needs a 3:1 ratio.
Images of Text
Use real text instead of text baked into images. Images of text can't be resized, translated, or read by screen readers.
✓ Do
Set all headlines, labels, and body copy as live text in Figma✗ Don't
Drop in a PNG of a stylised heading because the font isn't availableException: logos and wordmarks where the text is part of the brand identity.
Non-text Contrast
UI components and icons must have a contrast ratio of at least 3:1 against their background. This applies to anything interactive or meaningful — buttons, inputs, checkboxes, icons, dividers.
✓ Do
Check the border of an input field, the stroke of an icon, and the outline of a button against their background✗ Don't
Use a light grey button border on white just because the fill colour looks fineSensory Characteristics
Never design UI that can only be understood by its appearance, position, or sound. Instructions like "tap the blue icon" or "use the button on the right" break down for users who can't perceive those characteristics.
✓ Do
Design labels and instructions that name the element directly ("tap Save")✗ Don't
Design UI that requires copy like "see the panel on the left" to be understoodThree Flashes
Nothing on screen should flash more than 3 times per second. Flashing content can trigger seizures in users with photosensitive epilepsy.
✓ Do
Keep animations smooth and below the threshold; test any looping motion before handoff✗ Don't
Use rapid strobe effects, fast-cycling highlights, or attention-grabbing flashesMultiple Ways
Users should be able to reach any screen through more than one path. Relying on a single navigation route creates dead ends for users who navigate differently.
✓ Do
Design search, breadcrumbs, sitemaps, or related links as additional pathways to key screens✗ Don't
Design a flow where the only way to reach a screen is through one specific sequenceFocus Visible
Every interactive element must show a visible focus indicator when selected via keyboard. If a keyboard user can't see where they are on screen, they're effectively lost.
✓ Do
Design a distinct focus style for every interactive component — buttons, links, inputs, tabs✗ Don't
Remove the default browser focus ring without replacing it with something equally visibleFocus Not Obscured (Minimum) New 2.2
When an element receives focus, it must not be completely hidden by other content. Sticky headers, floating toolbars, cookie banners, and modals are common culprits.
✓ Do
Check that focused elements remain at least partially visible when sticky UI is present on screen✗ Don't
Design a sticky header that covers the top row of interactive elements when the user scrollsTarget Size (Minimum) New 2.2
Interactive targets must be at least 24×24px. Aim for 44×44px for touch interfaces. Small targets are hard to hit for anyone using a finger, stylus, or with limited motor control.
✓ Do
Set minimum tap/click target sizes in your design system; add invisible padding around small icons✗ Don't
Design icon-only buttons at 16px and assume the visual size is the same as the tap sizeConsistent Navigation
Navigation that appears across multiple screens must appear in the same place and order every time. Inconsistency forces users to relearn the interface on every screen.
✓ Do
Lock navigation components in your design system; don't reorder items between screens✗ Don't
Move the back button or rearrange nav items based on what "feels right" for a specific screenConsistent Identification
Components that do the same thing must look the same and be named the same across the product. A search icon that changes between screens creates unnecessary confusion.
✓ Do
Build a design system where every component has one visual form and one consistent name✗ Don't
Use "Submit," "Send," and "Go" interchangeably for the same action across different screensConsistent Help New 2.2
If help is available (chat, FAQ, support link), it must appear in the same location on every screen. Users who need help shouldn't have to hunt for it differently each time.
✓ Do
Fix the position of help entry points in your layout grid — consistent across all screens✗ Don't
Show a help icon in the header on some screens and in the footer on othersDesign → Dev criteria
The design decision is yours — but dev needs a spec to implement it correctly. Each card tells you exactly what to document before handoff.
Non-text Content
Every image, icon, and illustration needs declared intent. You're the only one who knows if it's decorative (ignore it) or meaningful (describe it). Dev can't make this call from looking at the design.
✓ Do
Annotate every non-text element as either "decorative" or provide suggested alt text✗ Don't
Leave icons and illustrations unannotated and assume dev will figure out the intentInfo and Relationships
The visual hierarchy you create — heading sizes, groupings, table structures, form layouts — needs to be encoded semantically in code. Dev can't guess your intended structure from visual styling alone.
✓ Do
Annotate heading levels (H1/H2/H3), table structures, and logical form groupings on every screen✗ Don't
Assume that because something looks like a heading, dev will automatically code it as oneMeaningful Sequence
Screen readers read in DOM order, not visual order. If your layout has columns, overlapping elements, cards, or any non-linear flow — dev needs to know the intended reading sequence.
✓ Do
Add numbered reading order annotations to any layout that isn't strictly top-left to bottom-right✗ Don't
Design multi-column or overlapping layouts without specifying the intended reading orderIdentify Input Purpose
Every input field needs its purpose declared so browsers can offer autofill correctly. You define what the field is for; dev implements the correct autocomplete attribute.
✓ Do
Label the purpose of every form field explicitly — name, email, phone, street address, city, etc.✗ Don't
Use vague labels like "Field 1" or "Enter details" — dev needs to know what type of data is expectedAudio Control
If any screen has auto-playing audio, a visible pause/stop control must be designed. Dev implements the behavior, but the control has to exist in your design first.
✓ Do
Design a visible, clearly labelled pause/stop control for any screen with auto-playing audio or video✗ Don't
Hand off screens with auto-playing media and leave the control placement undefinedContent on Hover or Focus
Tooltips, dropdowns, and hover cards that appear on focus must behave in three specific ways — they must be dismissable without moving focus, hoverable without disappearing, and persistent until dismissed. You define the behavior; dev implements it.
✓ Do
Specify dismissal method (e.g. Escape key), hover persistence, and how long the content stays visible✗ Don't
Design tooltips without specifying their behavior — "appears on hover" is not enough informationKeyboard
Every interactive element must be reachable and operable via keyboard alone. You need to confirm that all interactions are covered in your design — dev then implements the keyboard handlers.
✓ Do
Create an inventory of every interactive element per screen; flag any custom interactions (drag, swipe, gesture)✗ Don't
Design interactions that only work with a mouse or touch gesture without specifying a keyboard alternativeTiming Adjustable
If any screen has a timeout or session expiry, a visible UI to extend or dismiss it must be designed. The warning UI is your responsibility; the logic behind it is dev's.
✓ Do
Design a timeout warning dialog with clear options to extend, save, or dismiss — before the session expires✗ Don't
Rely on dev to design the timeout warning — if it's not in your frames, it probably won't existPause, Stop, Hide
Carousels, animations, auto-scrolling content, and tickers all need visible controls. You define where and how they appear; dev implements the behavior.
✓ Do
Include pause, stop, or hide controls in the design for every piece of moving or auto-updating content✗ Don't
Design auto-playing carousels or tickers without including visible controls in the frameFocus Order
The order in which a keyboard user tabs through elements must match the logical reading and interaction order. You define the intended sequence; dev implements it in the DOM.
✓ Do
Add numbered tab order annotations to every screen with modals, multi-column layouts, or custom component flows✗ Don't
Assume tab order will match visual order — CSS layout and visual positioning often don't match DOM orderLink Purpose (In Context)
Link labels must make sense in context. "Click here," "Read more," and "Learn more" fail this — especially when multiple appear on the same screen. Designer and content owner must align on meaningful labels; dev implements accessible names.
✓ Do
Write link labels that describe the destination or action — "Read the full report," "Download invoice #1042"✗ Don't
Use "Read more" or "Click here" as link labels — they're meaningless to screen reader users navigating by linksHeadings and Labels
The visual heading hierarchy needs to be explicitly mapped to heading levels. What looks like an H2 visually must be coded as an H2 — dev needs you to tell them which level each heading is.
✓ Do
Annotate every heading with its intended level (H1, H2, H3, H4) on each screen✗ Don't
Use heading size as a purely visual decision — "big text" and "H1" are not the same thingPointer Gestures
Any interaction requiring a multi-touch gesture (pinch to zoom, two-finger swipe, rotate) must also be achievable with a single pointer. You design both paths; dev implements them.
✓ Do
For every multi-touch gesture, design an equivalent single-tap or button-based alternative✗ Don't
Design interactions that only work with two fingers without providing a single-pointer alternativeLabel in Name
The visible text label on a button or link must be contained within its accessible name. If a button says "Save," the screen reader cannot call it "Submit." The visible label must match or be part of the programmatic name.
✓ Do
Ensure the accessible name you specify for every component includes the exact visible label text✗ Don't
Use an aria-label that replaces or contradicts the visible label — "Save" visible, "Submit form" as aria-labelMotion Actuation
If any feature is triggered by device motion — shake to undo, tilt to navigate, gyroscope-based interaction — an equivalent on-screen UI control must be designed.
✓ Do
Design an on-screen button or control equivalent for every motion-triggered feature✗ Don't
Ship motion-triggered interactions without an on-screen alternative — not all users can physically move their deviceDragging Movements New 2.2
Any drag interaction — reordering lists, sliders, kanban cards, resizable panels — needs a single-pointer alternative that doesn't require dragging. You design both; dev implements both.
✓ Do
For every drag-based UI element, design an equivalent interaction using taps, clicks, or keyboard controls✗ Don't
Design sortable lists, drag-to-resize panels, or sliders without a non-drag alternativeError Identification
Error states must be designed for every form field that can fail validation. You design what the error state looks like and write the message; dev implements the detection logic and triggers the right state.
✓ Do
Design an explicit error state for every input field — with color, icon, and a descriptive error message✗ Don't
Hand off forms without designed error states and expect dev to style them from scratchLabels or Instructions
Every form field needs a persistent visible label or clear instruction. Placeholder text alone doesn't count — it disappears when the user starts typing.
✓ Do
Design visible labels above or beside every input; use placeholder text only as supplementary guidance✗ Don't
Use placeholder text as the only label — users lose context the moment they start typingError Suggestion
Where a validation error occurs and a fix is known, a suggestion must be surfaced in the UI. "Invalid date" tells a user what's wrong. "Enter a date in DD/MM/YYYY format" tells them how to fix it.
✓ Do
Write specific, actionable error suggestion copy for every common error scenario — and design where it appears✗ Don't
Use generic error messages like "Invalid input" — they tell the user nothing about what to do nextError Prevention
For any legal, financial, or irreversible action — deleting an account, submitting a payment, confirming a booking — design must include a review step, confirmation dialog, or undo mechanism.
✓ Do
Design a confirmation step or review screen for every high-stakes or irreversible action✗ Don't
Let destructive or financial actions trigger immediately on a single tap without any confirmationRedundant Entry New 2.2
Don't ask users for information they've already provided in the same session. Multi-step forms, checkout flows, and onboarding sequences are common places this breaks down.
✓ Do
Audit every multi-step flow — pre-fill or summarise previously entered information rather than asking again✗ Don't
Ask for name, email, or address a second time in the same session if the user already provided itAccessible Authentication New 2.2
Login and verification flows must not rely solely on cognitive tests — no "retype the code you memorised" or puzzle-solving as the only option. Design must include at least one alternative path that doesn't require memorisation or transcription.
✓ Do
Design authentication flows that allow copy-paste, biometrics, magic links, or password managers✗ Don't
Design a login that forces users to memorise and retype an OTP without allowing paste or an alternative methodName, Role, Value
Every interactive component — button, toggle, modal, tab panel, accordion — needs its name, role, and all possible states documented so dev can implement correct ARIA markup and screen reader announcements.
✓ Do
Annotate every component with its name, its role (button, checkbox, dialog…), and all interactive states✗ Don't
Hand off custom components — icon buttons, toggles, custom dropdowns — without naming their role and statesStatus Messages
Success banners, loading states, error alerts, and form confirmations need to be announced to screen readers without moving keyboard focus. You define where and when they appear; dev implements the live region behavior.
✓ Do
Design every status message as a distinct component with a defined trigger — and mark that focus must not shift to it✗ Don't
Design toast notifications or success banners without specifying that they should not steal keyboard focusDev-only criteria
No design input required for these 12 criteria. They are resolved entirely in code — semantic HTML, ARIA, CSS units, and browser-level behaviour. The green block on each card tells you what to implement and test.
Orientation
Content must not be restricted to a single display orientation — portrait or landscape — unless that restriction is essential to the function. Users with devices mounted in a fixed position depend on this.
✓ Do
Support both portrait and landscape orientations in CSS and JS; if locking is unavoidable, display a clear explanation to the user✗ Don't
Lock orientation in code as a convenience or stylistic choice — only lock it when the content genuinely cannot work otherwise (e.g. a piano keyboard)screen.orientation.lock() or CSS @media (orientation) to hide content. Test layouts in both orientations at common breakpoints.
Resize Text
Text must be resizable up to 200% without losing content or functionality. This is purely a CSS implementation concern — it depends entirely on using relative units instead of fixed pixels.
✓ Do
Userem or em for all font sizes; use min-height instead of height on text containers✗ Don't
Set font sizes inpx — pixel values ignore the user's browser font size preference and break at 200% zoomrem. Test by setting browser default font size to 32px (double the standard 16px) and verify no content is clipped, truncated, or overlapping.
Reflow
At 400% browser zoom (equivalent to a 320px viewport), content must reflow into a single column without requiring horizontal scrolling. Users with low vision zoom in significantly — horizontal scrolling forces them to track two axes simultaneously.
✓ Do
Implement responsive layouts that work at 320px wide; use flexbox or CSS grid with wrapping; avoid fixed-width containers wider than 320px✗ Don't
Use fixed-width containers,overflow-x: scroll as a layout solution, or assume 768px is the smallest viewport to supportText Spacing
When users override text spacing via a browser extension or user stylesheet, no content or functionality should break. This is about writing CSS that doesn't snap under spacing pressure.
✓ Do
Usemin-height instead of height on any element containing text; allow containers to grow naturally when spacing increases✗ Don't
Set fixed heights on text containers, useoverflow: hidden on elements with text, or hardcode line heights that can't flexline-height: 1.5 !important; letter-spacing: 0.12em !important; word-spacing: 0.16em !important; p { margin-bottom: 2em !important; } — verify no text is clipped or overlapping.
No Keyboard Trap
If keyboard focus can move into a component, it must be able to move out — using standard keys (Tab, Shift+Tab, Escape). Modal dialogs are the classic trap. When a modal opens, focus must be managed correctly and returned to the trigger on close.
✓ Do
Implement focus trapping inside open modals (Tab cycles within), Escape to close, and focus return to the trigger element on close✗ Don't
Open modals, drawers, or custom widgets without managing focus — keyboard users will be stuck behind the overlay or lost after closingCharacter Key Shortcuts
If single-character keyboard shortcuts (a letter, number, or punctuation key alone — no modifier) are implemented, users must be able to turn them off or remap them. They conflict with screen reader and speech input commands.
✓ Do
Require at least one modifier key (Ctrl, Alt, Cmd) for all keyboard shortcuts; or provide a settings toggle to disable single-key shortcuts✗ Don't
Implement shortcuts that fire on a single letter or number key without any modifier — they will clash with screen reader navigation commandskeydown/keyup listeners. Any that respond to a single character key without a modifier (Ctrl/Alt/Meta) need either a modifier added or a user-facing toggle to disable them.
Bypass Blocks
Keyboard users must be able to skip past repeated content blocks — navigation, headers, sidebars — to reach the main content directly. Without this, every page requires dozens of Tab presses before reaching the actual content.
✓ Do
Implement a "Skip to main content" link as the very first focusable element on every page; use correct ARIA landmark roles throughout✗ Don't
Hide or remove skip links because they look odd visually — make them visible on focus, invisible otherwise<a href="#main-content" class="skip-link">Skip to main content</a> as the first element in <body>. Style it off-screen by default, visible on :focus. Add id="main-content" to the <main> element. Use <nav>, <main>, <aside>, <header>, <footer> landmark elements correctly.
Pointer Cancellation
Actions should fire on the up-event (pointer release), not the down-event (pointer press). This gives users a chance to cancel by moving the pointer away before releasing — a critical safety net for accidental touches.
✓ Do
Useclick events for triggering actions — they fire on pointer up and include built-in cancellation behaviour✗ Don't
Usemousedown, pointerdown, or touchstart to trigger irreversible or destructive actionsmousedown / pointerdown / touchstart event listeners that trigger actions. Replace with click events. Exception: down-events are permitted for drag operations, piano keys, or other cases where the press itself is the interaction.
Page Titled
Every page or view must have a descriptive title that identifies its purpose. Screen readers announce the page title on load — it's how users confirm they've landed in the right place.
✓ Do
Set a unique, descriptive<title> for every page — format: "Page Name — Product Name" or "Step 2 of 4: Shipping — Checkout"✗ Don't
Use the same title on every page, leave it as the app name alone, or use the default framework placeholderdocument.title on every route change. Format: specific page context first, then product name (e.g. "Invoice #1042 — Billing — Acme App"). Never leave the title as just the product name across all pages.
Language of Page
The primary language of each page must be declared in the HTML lang attribute. Screen readers use this to select the correct pronunciation engine — the wrong language setting produces garbled output.
✓ Do
Set the correctlang attribute on the <html> element of every page — e.g. lang="en", lang="hi", lang="de"✗ Don't
Leave thelang attribute missing, empty, or set to the wrong language — and never default to lang="en" on non-English pages<html lang="xx"> where xx is a valid BCP 47 language tag. In multi-language apps, set lang dynamically on route change to match the current locale.
Language of Parts
When content switches language mid-page — a French quote in an English document, a Spanish product name in an English interface — the language change must be marked up so screen readers switch pronunciation correctly.
✓ Do
Wrap any inline content in a different language with the correctlang attribute — e.g. <span lang="fr">Bonjour</span>✗ Don't
Leave foreign language strings unmarked — the screen reader will attempt to pronounce them in the page's primary language, producing incorrect outputlang="xx" to the containing element — a <span>, <p>, or <blockquote> as appropriate. This does not apply to proper nouns or technical terms.
On Focus
When a UI element receives keyboard or pointer focus, it must not automatically trigger a context change — no navigation, no form submission, no content shifting. Focus means "I'm here," not "go."
✓ Do
Trigger context changes (navigation, submission, popups) only on explicit user actions — click, Enter key, or Space bar✗ Don't
Attach navigation or modal-open logic tofocus or mouseenter events alone — these fire without the user consciously choosing an actionfocus and blur event listeners. None should trigger navigation, form submission, or significant layout changes. Use click or keydown (Enter/Space) for intentional actions instead.
On Input
Changing a form control's value — selecting a radio button, choosing a dropdown option, ticking a checkbox — must not automatically trigger a context change unless the user was warned in advance.
✓ Do
Require an explicit submit action after form input changes; if auto-advance is genuinely needed, warn the user in the field label✗ Don't
Auto-submit forms, auto-navigate to another page, or open modals when a user selects a radio button or changes a dropdownchange and input event listeners on form controls. None should trigger navigation or submission. Exception: date pickers that auto-advance between day/month/year fields are permitted if the label explains the behaviour ("selecting a month will advance to day").
Content criteria
Owned by writers, editors, media producers, and content strategists. Some criteria are shared — the purple "Your part" block on split cards tells you exactly what content is responsible for.
Audio-only and Video-only (Prerecorded)
Prerecorded audio-only content (podcasts, voice recordings) needs a text transcript. Prerecorded video-only content (silent walkthroughs, animations) needs either a transcript or an audio description track narrating what's happening visually.
✓ Do
Write accurate transcripts for all audio-only content; for silent video, write a descriptive text alternative covering all meaningful visual information✗ Don't
Publish audio or video content without a text alternative — users who are deaf, hard of hearing, or in a silent environment have no access to the informationCaptions (Prerecorded)
Every prerecorded video that contains audio must have synchronised captions. Auto-generated captions alone are not sufficient — they must be reviewed, corrected, and include speaker identification and meaningful non-speech sounds.
✓ Do
Review and correct auto-captions before publishing; include speaker names and notations like [applause] or [alarm sounds] where they carry meaning✗ Don't
Publish auto-generated captions without review — errors in speech recognition can make captions misleading or meaninglessAudio Description or Media Alternative
Prerecorded video must either have an audio description track narrating meaningful visual content, or a full text alternative that describes both the audio and the visual content in full.
✓ Do
Write audio description scripts that narrate visual information not conveyed in the dialogue — what's on screen, what people are doing, relevant text shown visually✗ Don't
Assume the dialogue alone conveys everything — key information shown visually (charts, demonstrations, text on screen) is invisible to users who can't see the videoCaptions (Live)
Live audio-video content — webinars, live streams, broadcasts, virtual events — must have real-time captions. Pre-prepared transcripts are not a substitute for synchronised live captions.
✓ Do
Arrange CART (Communication Access Realtime Translation) or an equivalent live captioning service for any streamed or broadcast event✗ Don't
Rely on auto-captions for live events or assume a post-event transcript satisfies this — it must be synchronised in real timeAudio Description (Prerecorded)
All prerecorded video must have an audio description track — a narration of meaningful visual information that isn't already conveyed in the main audio. This is separate from the captions requirement.
✓ Do
Script and produce audio descriptions that fit into natural pauses in the main audio; describe actions, scene changes, on-screen text, and visual context✗ Don't
Describe what's already said in the dialogue — audio descriptions fill the visual gaps, not repeat the speechNon-text Content Shared
Every meaningful image, icon, chart, and illustration needs a text alternative. Design flags which images are meaningful vs. decorative — content writes the actual alt text words.
✓ Do
Write alt text that conveys the purpose or content of the image — concise, specific, and written as if describing it to someone on the phone✗ Don't
Start alt text with "Image of…" or "Photo of…" — screen readers already announce it's an image; use that space for the actual descriptionSensory Characteristics Shared
Instructional copy must never reference UI elements only by their appearance, position, color, or sound. "Tap the green button" fails for colorblind users. "Click the icon on the right" fails for screen reader users.
✓ Do
Reference elements by their label or function — "tap Save," "select your country from the dropdown," "use the Search field"✗ Don't
Write instructions like "tap the blue button," "use the panel on the left," or "click the large icon at the top"Link Purpose (In Context) Shared
Link labels must make sense in context. Screen reader users often navigate by scanning a list of all links on a page — "Read more" repeated six times tells them nothing. The link text itself (or its immediate context) must describe where it goes or what it does.
✓ Do
Write link labels that describe the destination or action — "Download the Q3 report," "Read the full case study," "Book a 30-minute call"✗ Don't
Use "Read more," "Click here," "Learn more," or "See details" as standalone link text — they are meaningless out of contextLanguage of Parts Shared
When content switches language mid-page — a French quote, a Spanish product name, a phrase in another script — the language change must be marked up in code. Content needs to flag these switches so dev can implement the correct markup.
✓ Do
Clearly mark any non-primary-language content in your copy deck so dev knows to apply the correctlang attribute✗ Don't
Silently include foreign language phrases without flagging them — dev cannot reliably identify language switches from reading the copy aloneLabels or Instructions Shared
Every form field needs a clear, persistent label and — where the format isn't obvious — an instruction. Design places the label; content writes the words. Vague labels ("Details," "Info") create friction for all users and confusion for screen reader users.
✓ Do
Write specific, plain-language labels — "Date of birth (DD/MM/YYYY)," "Mobile number," "Company registration number"✗ Don't
Use single-word labels like "Name" for a field that expects a full legal name, or leave format instructions out of fields with strict validation rulesError Suggestion Shared
When validation fails and a fix is known, the suggestion must be surfaced in the UI. Design defines where it appears; content writes the words. "Invalid input" is an error identification. "Enter a date in DD/MM/YYYY format" is an error suggestion — and it's what this criterion requires.
✓ Do
Write specific, actionable error suggestions for every common failure scenario — what went wrong and exactly how to fix it✗ Don't
Use generic messages like "Invalid input," "Error," or "Something went wrong" — they tell the user nothing about how to proceed