Skip to main content
Custody & Agency — Internal Reference

WCAG 2.1 Testing &
Remediation Documentation

Complete auditor reference for all 50 WCAG 2.1 Level A and AA success criteria — including plain-language definitions, step-by-step testing procedures, and real-world remediation examples.

P1 — Perceivable (1.1–1.4)
P2 — Operable (2.1–2.5)
P3 — Understandable (3.1–3.3)
P4 — Robust (4.1)
1.1.1 Non-text Content Level A

Every image, icon, button icon, chart, CAPTCHA, and decorative element must have an appropriate text alternative so screen reader users receive the same information.

  • Inspect images with browser DevTools — check for alt attribute on <img> tags.
  • Decorative images should have alt='' and role='presentation'.
  • Icon-only buttons need aria-label or visually-hidden text.
  • Run Axe DevTools or WAVE — both flag missing alt text automatically.
A 'Search' button showing only a magnifying glass icon has aria-label='Search' added so NVDA announces 'Search button' rather than just 'button'.
1.2.1 Audio-only / Video-only (Prerecorded) Level A

Pre-recorded audio-only content (like a podcast) needs a text transcript. Pre-recorded video-only content (like a silent product demo) needs an audio track or text description.

  • Locate any audio-only or video-only media on the site.
  • Verify a full text transcript is linked near the player.
  • For video-only, verify an audio description track or text description is available.
A promotional slideshow video with no speech includes a toggle button that opens a text panel describing each slide in sequence.
1.2.2 Captions (Prerecorded) Level A

Prerecorded synchronized media (video with audio) requires accurate captions that identify speakers, sound effects, and other relevant audio information.

  • Play all video content and verify captions are available and togglable.
  • Check that auto-generated captions have been human-reviewed for accuracy.
  • Captions must reflect speech, identify speakers, and note meaningful audio events (e.g. [applause]).
A client testimonial video includes closed captions enabled by default, verified against a reviewed transcript for accuracy.
1.2.3 Audio Description or Media Alternative (Prerecorded) Level A

Synchronized media (video+audio) must offer either an audio description of visual-only content OR a full text alternative that presents the same information.

  • Watch all videos — note any information conveyed visually but not spoken (charts, graphs, actions).
  • Verify audio description track is available OR a text alternative describes all visual content.
A training webinar video offers an extended text summary below describing all on-screen demos not covered in the narration.
1.2.4 Captions (Live) Level AA

Live synchronized media (e.g. live webinars, broadcasts) must have real-time captions. Auto-captions from platforms like YouTube or Zoom may qualify if accurate.

  • If the site streams live content, verify real-time captions are available.
  • Test using a live streaming event and enable captions.
  • Note: auto-captions must be accurate to qualify.
Live webinar sessions hosted via the site's streaming widget use a CART captioning service, verified during test broadcasts.
1.2.5 Audio Description (Prerecorded) Level AA

All prerecorded video with audio must include an audio description track that narrates significant visual information not conveyed in the main audio.

  • Review all video content frame-by-frame for visual information not spoken.
  • Verify an audio description track exists and activates via a player control.
  • Alternative: use an extended audio description if pauses in content are insufficient.
A product demo video includes an AD track describing the interface being demonstrated, e.g. 'The cursor moves to the Settings icon in the top-right corner.'
1.3.1 Info and Relationships Level A

The visual structure — headings, lists, tables, form labels — must be communicated in the markup so assistive technologies can interpret relationships, not just appearance.

  • Run NVDA and navigate by heading with the H key — verify heading levels are logical.
  • Verify tables use <th scope='col'> for header cells.
  • Check form inputs have associated <label> elements (not just placeholder text).
  • Lists must use <ul>/<ol> — not styled <div>s.
A 3-column comparison table uses <th scope='col'> headers so NVDA announces 'Plan, Bronze column' as users navigate cells.
1.3.2 Meaningful Sequence Level A

When content is linearized (read top-to-bottom without CSS), the reading and navigation order must remain logical and meaningful.

  • Disable CSS in the browser (DevTools > uncheck Stylesheet) and verify content order still makes sense.
  • In NVDA, browse reading mode — check the announced sequence is logical.
  • Watch for visually reordered content (CSS order or position:absolute) that breaks DOM order.
A sidebar column appearing visually to the left of the main content is sourced after the main content in the DOM, so screen readers read main content first.
1.3.3 Sensory Characteristics Level A

Instructions for operating features must not rely solely on shape, color, size, visual location, or sound. Text labels must always accompany sensory references.

  • Scan copy for instructions like 'click the red button' or 'the square icon on the left' — these must include a text label.
  • Also review audio-triggered instructions not supported by text cues.
A form instruction reading 'Click the green Submit button' is updated to 'Click the Submit button (labeled Submit)' so users who cannot perceive color can still follow instructions.
1.3.4 Orientation Level AA

Content must not be locked to portrait or landscape orientation unless that specific orientation is essential to the function (e.g., a piano keyboard app).

  • Use Chrome DevTools device emulator — rotate between portrait/landscape for each page.
  • Verify no 'please rotate your device' blocking message appears for non-essential content.
  • Confirm all page content reflows and remains functional in both orientations.
All site pages rotate freely between portrait and landscape. No page forces a specific orientation.
1.3.5 Identify Input Purpose Level AA

The purpose of each input field collecting personal information (name, email, phone, address) must be determinable by user agents so browsers and AT can autofill or adapt the display.

  • Inspect form fields — verify autocomplete attributes match field purpose (e.g. autocomplete='email', autocomplete='given-name').
  • Test by enabling browser autofill — fields should be correctly identified.
The contact form uses autocomplete='given-name' and autocomplete='email' on the Name and Email fields respectively.
1.4.1 Use of Color Level A

Color must not be the sole visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.

  • View the page in grayscale (Chrome DevTools > Rendering > Emulate vision deficiency: Achromatopsia).
  • Verify all status indicators (error, success) also use icons, text, or patterns.
  • Check that links mid-paragraph have a non-color distinguisher (underline, bold).
Form validation errors show a red border AND an error icon AND descriptive error text — passing even if a user cannot perceive red.
1.4.2 Audio Control Level A

If any audio plays automatically for more than 3 seconds, users must be able to pause, stop, or control the volume independently of the system volume.

  • Load each page — note any auto-playing audio.
  • Verify a visible, keyboard-operable pause/stop control is present at the top of the page.
  • Auto-play with background music is a common fail for this criterion.
The homepage hero video has muted auto-play only — no auto-playing audio track is present.
1.4.3 Contrast (Minimum) Level AA

Text and images of text must have a contrast ratio of at least 4.5:1. Large text (18pt+ or 14pt bold+) requires 3:1. Decorative text and logos are exempt.

  • Use WebAIM Contrast Checker or TPGi Colour Contrast Analyser on all text/background combinations.
  • Pay attention to disabled state text, placeholder text, and text over images.
  • Check hover states, focus states, and component state variations.
Body text #333333 on white background achieves 12.6:1 ratio. Gold accent text (#b45309) on white achieves 4.7:1 — both passing.
1.4.4 Resize Text Level AA

Text must remain readable and functional when the user increases text size up to 200% using browser zoom only, without loss of content or functionality.

  • In Chrome, set zoom to 200% (Ctrl++ or Settings > Zoom).
  • Navigate all pages — check for overlapping text, truncated labels, or disappearing content.
  • Also test text-only zoom (Firefox View > Zoom > Zoom Text Only).
At 200% zoom, the navigation menu adapts to a hamburger menu and all content reflows correctly with no overflow or truncation.
1.4.5 Images of Text Level AA

Text conveying information should be real HTML text, not baked into an image. Images of text are only acceptable for logos or when a particular text presentation is essential.

  • Inspect banners, hero sections, and promotional graphics — verify text is real HTML, not embedded in images.
  • Right-click > Inspect any suspicious text-like graphics to confirm element type.
All headings and body copy are HTML text styled with CSS. Only the company logo uses an image of text (exempt as a logotype).
1.4.10 Reflow Level AA

Content must be viewable at 400% zoom (equivalent to 1280px viewport at 320px width) without requiring horizontal scrolling, except for content that requires two-dimensional scrolling (maps, data tables).

  • Set browser viewport to 320px wide (DevTools device emulation) and verify content flows vertically without horizontal scrollbar.
  • Alternatively, zoom to 400% on a 1280px wide screen.
At 320px viewport width, all page content stacks into a single column. The data table becomes horizontally scrollable — exempt as a two-dimensional data component.
1.4.11 Non-text Contrast Level AA

Non-text UI components (buttons, checkboxes, form fields, focus indicators, charts) must maintain a 3:1 contrast ratio against adjacent colors, in all states.

  • Use Colour Contrast Analyser on button borders, input borders, checkbox borders, and focus rings.
  • Check default, hover, focus, disabled, and error states.
  • Icon-only buttons' icons must also pass 3:1.
Form input borders (#6b7280 on white) achieve 4.6:1. Focus rings (3px solid #b45309) achieve 4.7:1 — all passing.
1.4.12 Text Spacing Level AA

Users must be able to override text spacing (line height to 1.5x, letter spacing to 0.12em, word spacing to 0.16em, paragraph spacing to 2em) without losing content or functionality.

  • Apply the WCAG Text Spacing bookmarklet (Steve Faulkner's) and verify no content clips, overlaps, or becomes inaccessible.
  • Check truncated containers with fixed heights.
After applying text spacing overrides, all card components expand to accommodate the larger spacing. No content is hidden by overflow:hidden with a fixed height.
1.4.13 Content on Hover or Focus Level AA

Additional content that appears on hover or focus (tooltips, submenus, popovers) must: (1) be dismissable without moving focus, (2) be hoverable without disappearing, and (3) persist until dismissed or focus moves away.

  • Trigger each hover/focus tooltip — then press Escape. Tooltip must dismiss.
  • Move mouse from trigger onto the tooltip itself — tooltip must stay visible.
  • Verify tooltip doesn't auto-hide after a short timer.
Navigation dropdown menus remain open when the user moves the mouse over them. Pressing Escape dismisses them. They only close when focus leaves.
2.1.1 Keyboard Level A

All interactive functionality — links, buttons, form inputs, modals, drag-and-drop — must be operable using a keyboard alone, with no mouse required.

  • Unplug/disable mouse. Navigate the entire site using Tab, Shift+Tab, Enter, Escape, and arrow keys.
  • Verify every interactive element is reachable and operable.
  • Custom widgets (sliders, date pickers) must implement ARIA keyboard patterns.
All modal dialogs trap focus inside while open and are closed with Escape. The custom date picker is operable with arrow keys per ARIA authoring practices.
2.1.2 No Keyboard Trap Level A

If keyboard focus can move into a component (modal, embedded media player), the user must be able to move focus out using Tab, Shift+Tab, or Escape — without requiring AT or non-standard keystrokes.

  • Keyboard into every interactive component — modals, carousels, date pickers.
  • Verify Tab or Escape exits and returns focus to context.
  • A keyboard trap here is a blocker — it renders the page inoperable for keyboard users.
When the contact form modal closes, focus returns to the 'Contact Us' button that triggered it. No keyboard trap exists.
2.1.4 Character Key Shortcuts Level A

If the site implements single-keystroke shortcuts (e.g., 'S' to Search), users must be able to turn them off, remap them to include a modifier key (Ctrl/Alt), or disable them while a component has focus.

  • Check if any keyboard shortcuts are implemented in JavaScript.
  • Test shortcut conflicts with NVDA's shortcut keys.
  • If no single-key shortcuts exist, this criterion passes by default.
The site uses no single-character keyboard shortcuts. This criterion passes by default.
2.2.1 Timing Adjustable Level A

If content has a time limit (session timeout, timed quiz, auto-expiring cart), users must be able to turn off the limit, adjust it to at least 10x the default, or be warned before time expires and given at least 20 seconds to extend it.

  • Identify any session timeouts, timed carousels, or auto-expiring forms.
  • Verify a warning dialog appears with an option to extend the session.
  • Exception: real-time auctions or events where time is essential.
The secure login session times out after 15 minutes. A dialog appears 2 minutes before expiry offering a 'Stay Logged In' button, giving users sufficient time to respond.
2.2.2 Pause, Stop, Hide Level A

Any content that moves, blinks, scrolls, or auto-updates for more than 5 seconds must have a pause, stop, or hide mechanism, unless it is essential.

  • Identify auto-rotating carousels, ticker feeds, and animated content.
  • Verify a visible pause button exists (not just on hover).
  • Background animations (CSS) must respect prefers-reduced-motion.
The homepage testimonial carousel has a visible Pause button. CSS animations use @media (prefers-reduced-motion: reduce) to stop all motion.
2.3.1 Three Flashes or Below Threshold Level A

No content may flash more than 3 times per second unless the flashing area is very small or below the general flash and red flash thresholds, to prevent seizure risk.

  • Use the Photosensitive Epilepsy Analysis Tool (PEAT) or Harding FPA to analyze any video or animation for threshold violations.
  • For simple implementations, observe GIFs and animations — nothing should flash rapidly.
All GIFs and CSS animations transition smoothly. No strobe-like flashing or rapid color alternation exists on the site.
2.4.1 Bypass Blocks Level A

A mechanism must exist to allow users to skip over repetitive navigation blocks and get directly to main content — typically implemented as a 'Skip to Main Content' link.

  • Press Tab as the very first action on page load — a 'Skip to Main Content' link must appear or be the first focusable element.
  • Activate the link — verify focus jumps to the <main> element.
Pressing Tab on any page reveals a 'Skip to Main Content' link in the top-left corner. Activating it moves focus to the id='main-content' section.
2.4.2 Page Titled Level A

Every HTML page must have a descriptive <title> element that identifies both the specific page and the site name, enabling users to identify the page without reading its full content.

  • Check browser tab text on each page — must be unique and descriptive.
  • Run document.title in the DevTools console for each page.
  • Pattern: 'Page Name | Site Name'.
All pages have unique titles following the pattern 'Services | Custody & Agency'. The title matches the H1 heading of each page.
2.4.3 Focus Order Level A

The order in which interactive elements receive keyboard focus must be logical and intuitive, following the visual reading order so users don't jump unexpectedly across the page.

  • Tab through the entire page without a mouse and verify the sequence is top-left to bottom-right, matching visual layout.
  • Watch for focus jumping from header to footer unexpectedly.
  • Avoid positive tabindex values — they override the natural DOM order.
Tab order follows visual layout: Skip link > Logo > Navigation > Main content > Footer. No tabindex values above 0 are used.
2.4.4 Link Purpose (In Context) Level A

The purpose of each link must be determinable from the link text alone, or from the link text plus its surrounding context (paragraph, list item, table cell, or ARIA label).

  • List all links on the page — identify any that say 'Click here', 'Read more', 'Learn more' without context.
  • In NVDA, press Insert+F7 to open the links list — all links must be self-explanatory.
  • Fix by adding aria-label or aria-describedby, or rewriting the link text.
'Read more about our Compliance Services' instead of bare 'Read more'. Icon links use aria-label='View Compliance Services page'.
2.4.5 Multiple Ways Level AA

There must be more than one way to find any page within a set of pages — typically satisfied by providing both site navigation AND a search function (or site map).

  • Verify the site has a primary navigation menu.
  • Verify a search function, site map, or related links exist as an alternative discovery path.
The site provides a top navigation menu, a footer with page links, and a search field — three distinct ways to find any page.
2.4.6 Headings and Labels Level AA

Section headings and form labels must be descriptive enough to help users understand the content they organize or the input they control. Vague headings like 'Info' or 'Details' are insufficient.

  • Review all H1–H6 elements — verify each clearly describes the section beneath it.
  • Review all form labels — verify they unambiguously describe what the field expects.
  • Avoid generic labels like 'Name' where 'First Name' or 'Company Name' would be clearer.
The contact form uses labels 'Your Full Name', 'Work Email Address', and 'How can we help you?' — each clearly describes the expected input.
2.4.7 Focus Visible Level AA

Any element receiving keyboard focus must have a visible focus indicator — typically a border, outline, or highlight that clearly distinguishes the focused element from its surroundings.

  • Tab through the page without a mouse — a visible indicator must follow focus at all times.
  • Verify CSS does NOT include outline: none or outline: 0 without an alternative focus style.
  • WCAG 2.2 adds minimum size and contrast requirements — applying those here is best practice.
All interactive elements display a 3px solid gold (#b45309) outline with 3px offset on focus, achieving 4.7:1 contrast against white backgrounds.
2.5.1 Pointer Gestures Level A

All functionality that uses multipoint (pinch-zoom) or path-based (swipe) gestures must also be operable with a single pointer — a single tap, click, or with an accessible alternative.

  • Identify any swipe carousels, pinch-zoom maps, or drag components.
  • Verify each has button alternatives (Previous/Next arrows, Zoom In/Out buttons).
The image carousel responds to touch swipe AND has visible Previous/Next buttons operable with a single tap or keyboard.
2.5.2 Pointer Cancellation Level A

For single-pointer interactions, the function must not be triggered on the 'down event' (mousedown/touchstart) unless essential. Users must be able to cancel accidental activation by moving the pointer off the target before releasing.

  • Click and drag off buttons — verify activation only fires on mouseup when pointer is still on target.
  • Verify no critical function fires immediately on mousedown.
All buttons trigger on click (mouseup), not mousedown. Dragging off a button before releasing cancels the action.
2.5.3 Label in Name Level A

For UI components with a visible text label, the accessible name used by AT must contain (or begin with) that visible label text, so voice control users can activate the component by speaking its label.

  • In NVDA, navigate to each button and form control — verify the announced name matches the visible label.
  • Check for icon buttons with aria-label that doesn't include the visible text.
  • A 'Submit' button with aria-label='Send Form' would fail — the label must contain 'Submit'.
A 'Download Report' button has aria-label='Download Accessibility Report PDF' — contains 'Download' so voice control activates correctly on 'click Download'.
2.5.4 Motion Actuation Level A

Functionality triggered by device motion (shake, tilt, gyroscope) must have an alternative UI control, and users must be able to disable motion actuation to prevent accidental triggering.

  • Identify any features using DeviceMotionEvent or DeviceOrientationEvent.
  • Verify alternate UI controls exist and a setting to disable motion input is available.
  • If no motion features exist, this criterion passes by default.
No device motion features are implemented. This criterion passes by default.
3.1.1 Language of Page Level A

The default human language of each page must be identified in the HTML markup via the lang attribute on the <html> element so screen readers use the correct pronunciation engine.

  • Inspect the <html> opening tag on each page.
  • Verify lang='en' (or appropriate language code) is present.
  • A missing or incorrect lang attribute causes screen readers to mispronounce content.
All pages include <html lang='en'>. NVDA announces content using the English pronunciation engine.
3.1.2 Language of Parts Level AA

When a page contains passages in a language different from the primary language, those passages must have their language identified with a lang attribute.

  • Review pages for foreign language quotes, phrases, or sections.
  • Verify lang attribute is applied to the wrapping element (e.g. <span lang='fr'>...</span>).
A French client testimonial is wrapped in <blockquote lang='fr'> so NVDA switches to the French pronunciation engine for that quote.
3.2.1 On Focus Level A

Moving keyboard or focus to a component must not automatically trigger a significant change of context (new window, page navigation, form submission). Context changes must be user-initiated.

  • Tab through all interactive elements — verify no page navigation or form submission fires on focus.
  • Auto-submit on focus is a common violation in legacy forms.
Focusing a dropdown does not submit the form or navigate the page. Users must explicitly choose an option and click Submit.
3.2.2 On Input Level A

Changing the value of a form input must not automatically trigger a significant context change (navigation, form submission) unless users are warned in advance.

  • Use all form controls — select dropdowns, checkboxes, radio buttons.
  • Verify no automatic page navigation or form submission occurs on input change without prior warning.
The 'Sort by' dropdown requires an explicit 'Apply' button click to filter results — no auto-submit on change.
3.2.3 Consistent Navigation Level AA

Navigation mechanisms that appear on multiple pages (site navigation, breadcrumbs, search) must appear in the same relative order on every page, although users may be able to reorder via personalization.

  • Compare the navigation structure across 5+ pages — verify order of nav items is consistent.
  • Check that the header and footer layout does not change between pages.
The primary navigation menu appears in the same order across all pages: Home > Services > Case Studies > Blog > Contact.
3.2.4 Consistent Identification Level AA

Components with the same function across multiple pages must be identified consistently — same label, same icon, same accessible name — so users can reliably recognize and operate them.

  • Audit recurring components: search, cart, login buttons across pages.
  • Verify the accessible name (aria-label or text) is identical for the same function on every page.
The search icon button is labeled aria-label='Search' on every page — never 'Find', 'Go', or 'Look up'.
3.3.1 Error Identification Level A

When an input error is automatically detected (required field left empty, invalid format), the error must be identified in text, describing the specific item and the nature of the error.

  • Submit each form with intentionally invalid or empty data.
  • Verify error messages appear as text (not just color change) and describe which field failed and why.
  • In NVDA, navigate to the error message — it must be announced.
Submitting the form without an email shows: 'Email address is required. Please enter a valid email address.' The error is linked to the input via aria-describedby.
3.3.2 Labels or Instructions Level A

Every form input must have a label that describes its purpose. Labels must be visible (not just placeholder text). Instructions about required format must appear before the input.

  • Scan all form inputs — verify a <label> is programmatically associated via for/id or wrapping.
  • Placeholder text is NOT a substitute for a label — it disappears on input.
  • Format hints (e.g. 'MM/DD/YYYY') must appear before the field, not only as placeholder.
All inputs have persistent visible labels above the field. The date field has 'Date of Birth (MM/DD/YYYY)' as a label, with the format hint always visible.
3.3.3 Error Suggestion Level AA

When an input error is detected and suggestions for correction are known, those suggestions must be provided to the user in text, unless doing so would jeopardize security or purpose.

  • Trigger validation errors — verify the error message not only identifies the problem but suggests a fix.
  • 'Invalid email' alone fails — 'Please enter a valid email address (e.g. [email protected])' passes.
An invalid phone number shows: 'Phone number format is incorrect. Please use the format: (555) 555-5555.'
3.3.4 Error Prevention (Legal, Financial, Data) Level AA

For pages involving legal, financial, or data-deletion transactions, users must be able to reverse, check, or confirm the submission before it is finalized.

  • Identify any irreversible actions (account deletion, payment submission, data changes).
  • Verify a review/confirmation step exists, or undo capability is provided.
The account cancellation flow presents a confirmation dialog: 'Are you sure you want to cancel your account? This action cannot be undone.' before processing.
4.1.1 Parsing Level A

HTML markup must be valid — elements properly nested, no duplicate IDs, complete start/end tags — so user agents and AT can parse and interpret the page correctly.

  • Run the W3C Markup Validation Service on each page URL.
  • Audit for duplicate id attribute values using DevTools: document.querySelectorAll('[id]').
  • Focus on errors that affect AT parsing (duplicate IDs, unclosed elements).
W3C Validator returns zero errors across all pages. No duplicate IDs exist — verified with a DOM audit script.
4.1.2 Name, Role, Value Level A

All user interface components (form fields, buttons, custom widgets) must have an accessible name, a determinable role, and states/properties that can be updated programmatically.

  • Use the Accessibility Tree in Chrome DevTools (Elements > Accessibility) for every interactive element.
  • Verify role is correct (button, link, textbox, etc.).
  • Check ARIA states update on interaction: aria-expanded, aria-selected, aria-checked.
The mobile menu toggle has aria-expanded='false' when closed, updating to aria-expanded='true' when the menu opens — verified in DevTools Accessibility panel.
4.1.3 Status Messages Level AA

Status messages (success notifications, error summaries, loading messages) that appear without receiving focus must be programmatically determinable via ARIA roles so AT users are informed without requiring a focus change.

  • Submit forms, trigger loading states — verify status messages use role='alert' (for errors) or role='status' (for success/info).
  • In NVDA, verify the message is announced automatically after a form submission.
A 'Form submitted successfully!' message uses role='status' — NVDA announces it automatically within 1 second of appearing without the user moving focus.