
A practical, step-by-step WCAG 2.2 AA testing guide anyone can apply—combining automated and manual checks
__________
What you'll learn
🤖 Automated Testing
- Test 1 — Lighthouse Accessibility
- Test 2 — Lighthouse SEO
- Test 3 — axe DevTools Audit
🧪 Manual Testing
- Test 4 — Non-HTML Links
- Test 5 — Online Forms
- Test 6 — Keyboard Tabbing
- Test 7 — Keyboard Focus
- Test 8 — Keyboard Skip Links
- Test 9 — Screen Reader
- Test 10 — Zoom 200%
- Test 11 — Responsive Web
- Test 12 — Mobile Chrome
- Test 13 — Mobile Safari
- Test 14 — Print Styles
__________
Overview
This guide provides a structured approach to accessibility testing, combining automated tools with essential manual testing procedures. It was developed and refined during our end-to-end accessibility audit of a large-scale education platform for New Zealand's Ministry of Education — and has been battle-tested against real-world government compliance requirements.
While automated tools can detect 30-50% of accessibility issues, manual testing is required to ensure a truly accessible experience.
Who should use this guide: QA testers, developers, designers, and content creators responsible for ensuring web accessibility compliance.
Standards covered: WCAG 2.2 Level AA (with notes on Level AAA where relevant).
What's New in WCAG 2.2
WCAG 2.2, released in October 2023, builds on 2.1 with nine new success criteria. Here's what's most relevant to typical web projects:
Level AA (Required for compliance)
- 2.4.11 Focus Not Obscured (Minimum) — When an element receives keyboard focus, it can't be fully hidden by sticky headers, footers, cookie banners, or other overlays. Users must be able to see what they're interacting with.
- 2.5.7 Dragging Movements — Any action that requires dragging (sliders, drag-and-drop, sortable lists) must have a single-pointer alternative. Users should be able to accomplish the same task with clicks or taps alone.
- 2.5.8 Target Size (Minimum) — Interactive elements must be at least 24×24 CSS pixels, or have sufficient spacing from adjacent targets. This is less strict than the AAA requirement of 44×44px but catches the worst offenders.
- 3.2.6 Consistent Help — If your site includes help mechanisms (contact links, chat widgets, FAQ links), they should appear in the same relative location across pages. Users shouldn't have to hunt for support.
- 3.3.7 Redundant Entry — Don't ask users to re-enter information they've already provided in the same session. If someone enters their address on step one, don't make them type it again on step three—auto-populate or let them confirm.
- 3.3.8 Accessible Authentication (Minimum) — Login flows can't rely on cognitive function tests like memorising passwords, transcribing codes, or solving puzzles—unless you provide an alternative method (password managers, passkeys, or email magic links).
Level AAA (Enhanced)
- 2.4.12 Focus Not Obscured (Enhanced) — Stricter than 2.4.11: focused elements can't be even partially hidden by other content.
- 2.4.13 Focus Appearance — Focus indicators must meet minimum size and contrast requirements, not just be "visible."
- 3.3.9 Accessible Authentication (Enhanced) — Stricter than 3.3.8: no cognitive tests at all, even if alternatives exist.
Where these are covered in this guide
Focus visibility is addressed in Test 7 (Keyboard Focus). Target sizes are checked in Test 11 (Responsive Web) and Tests 12–13 (Mobile Chrome and Safari). Dragging movements, authentication, redundant entry, and consistent help should be reviewed manually as part of your form and interaction testing.
Note: WCAG 2.2 deprecated Success Criterion 4.1.1 Parsing, as modern browsers now handle HTML parsing robustly. You'll still see it referenced in older documentation.
Prerequisites
1. Prepare Your Test Environment
Before beginning your audit:
- Document the pages to test — Create a list of representative pages covering all templates, components, and content types
- Use a consistent browser — Chrome is recommended for most automated tools
- Test in incognito/private mode — This prevents browser extensions from interfering with results
- Clear cache before testing — Ensures you're testing the current version of the site
2. Install Required Tools
Install these Chrome extensions before starting:
- Chrome Lighthouse
Purpose: Built-in (DevTools)
Install Link: Pre-installed in Chrome - axe DevTools
Purpose: Automated WCAG testing
Install Link: Chrome Web Store - WAVE
Purpose: Visual accessibility feedback
Install Link: Chrome Web Store - HeadingsMap
Purpose: Document outline checker
Install Link: Chrome Web Store
3. Set Up Issue Tracking
Create a system to log issues consistently:
- Group recurring issues — If the same problem appears across multiple pages, log it once with affected URLs
- Include reproduction steps — Document exactly how to reproduce each issue
- Capture screenshots — Visual evidence helps developers understand and fix issues
- Note WCAG criteria — Reference the specific success criterion each issue violates
__________
Test 1 — Lighthouse Accessibility (Automated)
📌 Overview
Lighthouse is Google's built-in auditing tool that evaluates accessibility against a subset of WCAG criteria. It provides a score out of 100 and flags specific issues with remediation guidance.
"These checks highlight opportunities to improve the accessibility of your web app. Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged." — Lighthouse Documentation
🌐 WCAG Coverage
Lighthouse tests elements of these success criteria (partial coverage):
- 1.1.1 Non-text Content
- 1.3.1 Info and Relationships
- 1.4.3 Contrast (Minimum)
- 2.4.1 Bypass Blocks
- 2.4.2 Page Titled
- 4.1.1 Parsing
- 4.1.2 Name, Role, Value
📋 Steps
- Open Chrome and navigate to your target page
- Open DevTools — Right-click anywhere and select "Inspect", or press
Ctrl+Shift+I(Windows) /Cmd+Option+I(Mac) - Navigate to Lighthouse tab — Click "Lighthouse" in the DevTools panel tabs (you may need to click
>>to see more tabs) - Configure the audit:
- Device: Select "Desktop" or "Mobile" as appropriate
- Categories: Check only "Accessibility" for focused results
- Mode: "Navigation" (default)
- Click "Analyze page load"
- Wait for the audit to complete — This typically takes 15-30 seconds
- Review results:
- Note the overall accessibility score
- Expand each failed audit for details
- Click "Learn more" links for remediation guidance
✅ Pass Criteria
- Accessibility score of 90 or above (aim for 100)
- No critical issues flagged in the "Accessibility" section
- All automated checks pass or have documented exceptions
❌ Fail Indicators
- Score below 90
- Any items in the "These items failed the accessibility check" section
- Contrast issues, missing alt text, or unlabelled form fields
⚠️ Common Issues
- Image missing alt text
WCAG: 1.1.1
Typical Fix: Add descriptivealtattribute - Low contrast text
WCAG: 1.4.3
Typical Fix: Increase colour contrast ratio - Missing form labels
WCAG: 1.3.1
Typical Fix: Add<label>elements withforattribute - Missing document title
WCAG: 2.4.2
Typical Fix: Add descriptive<title>element - Links without discernible text
WCAG: 2.4.4
Typical Fix: Add visible text or aria-label
💡 Tips
- Run Lighthouse multiple times — scores can vary slightly between runs
- Test both desktop and mobile configurations
- Export results as JSON or HTML for documentation
- Address "Opportunities" and "Diagnostics" sections too, as they often relate to accessibility
__________
Test 2 — Lighthouse SEO (Automated)
📌 Overview
While primarily focused on search engine optimisation, the SEO audit includes checks that directly impact accessibility, particularly around document structure, mobile usability, and content discoverability.
"These checks ensure that your page is optimized for search engine results ranking." — Lighthouse Documentation
Why Include SEO in Accessibility Testing?
SEO and accessibility share significant overlap:
- Semantic HTML benefits both screen readers and search crawlers
- Descriptive page titles help all users understand page content
- Proper heading hierarchy aids navigation for assistive technology users
- Mobile-friendliness ensures access for users on various devices
🌐 WCAG Coverage
Indirectly supports:
- 1.3.1 Info and Relationships
- 2.4.2 Page Titled
- 2.4.6 Headings and Labels
📋 Steps
- Open Chrome DevTools on your target page
- Navigate to the Lighthouse tab
- Configure the audit:
- Device: Select appropriate device type
- Categories: Check "SEO" (you can combine with Accessibility)
- Click "Analyze page load"
- Review results focusing on:
- Document has a
<title>element - Document has a meta description
- Page has successful HTTP status code
- Links have descriptive text
- Page isn't blocked from indexing (unless intentional)
- Tap targets are sized appropriately (mobile)
- Document has a
✅ Pass Criteria
- SEO score of 90 or above
- All content-related checks pass
- Mobile usability checks pass
❌ Fail Indicators
- Missing or duplicate page titles
- Links with generic text ("click here", "read more")
- Tap targets too small or too close together
- Document blocked from indexing unintentionally
⚠️ Common Issues
- Missing meta description
Impact: Reduced context for users
Typical Fix: Add<meta name="description"> - Links not crawlable
Impact: Content inaccessible
Use proper<a href>elementsTypical Fix: - Small tap targets
Impact: Difficult to interact on mobile
Typical Fix: Minimum 48×48px touch targets - Missing
langattribute
Impact: Screen readers may mispronounce
Typical Fix: Addlang="en"to<html>
__________
Test 3 — axe DevTools Audit (Automated)
📌 Overview
axe DevTools is an industry-leading automated accessibility testing tool developed by Deque Systems. It can detect 57% of WCAG issues automatically and provides detailed remediation guidance.
"axe DevTools allows you to easily find and fix 76-84% of accessibility errors before your applications get out of development." — Deque Systems
🌐 WCAG Coverage
axe tests against the complete WCAG 2.2 Level A and AA success criteria that can be automated. The top issues detected are:
- 1.4.3 Contrast (Minimum)
% of Issues: ~30% - 1.1.1 Non-text Content
% of Issues: ~15% - 1.3.1 Info and Relationships
% of Issues: ~12% - 4.1.2 Name, Role, Value
% of Issues: ~10% - 2.4.1 Bypass Blocks
% of Issues: ~8% - 4.1.1 Parsing
% of Issues: ~5% - 3.1.1 Language of Page
% of Issues: ~3%
📋 Steps
- Open Chrome and navigate to your target page
- Open DevTools (
Ctrl+Shift+I/Cmd+Option+I) - Navigate to the "axe DevTools" tab
- If not visible, click
>>to see more tabs - If not installed, install the extension first
- If not visible, click
- Click "Scan ALL of my page"
- Wait for the scan to complete
- Review results by category:
- Critical — Must fix; blocks access for some users
- Serious — Should fix; significantly impacts accessibility
- Moderate — Should fix; causes some difficulty
- Minor — Consider fixing; slight impact
- For each issue:
- Click to expand details
- Review the affected element(s)
- Read the "How to fix" guidance
- Use "Highlight" to locate the element on the page
- Check "More info" for WCAG references
✅ Pass Criteria
- Zero Critical issues
- Zero Serious issues
- Moderate and Minor issues documented with remediation plan
❌ Fail Indicators
- Any Critical or Serious issues present
- Recurring issues across multiple pages
- Issues affecting primary user journeys
⚠️ Common Issues
- Colour contrast insufficient
Severity: Serious
Typical Fix: Adjust foreground/background colours - Buttons without accessible name
Severity: Critical
Typical Fix: Add visible text oraria-label - Form inputs without labels
Severity: Serious
Typical Fix: Associate<label>with input - Heading levels skipped
Severity: Moderate
Typical Fix: Use sequential heading hierarchy - Empty links or buttons
Severity: Serious
Typical Fix: Add descriptive content - Missing
langattribute
Severity: Serious
Typical Fix: Addlangto<html>element
💡 Tips
- Test interactive states — Open modals, dropdowns, and accordions before scanning
- Test different page states — Scan pages with error messages, loading states, etc.
- Use "Intelligent Guided Tests" — The paid version includes manual test guidance
- Export results — Save reports for documentation and tracking
Integrating axe into CI/CD
Automated audits are valuable, but they're point-in-time snapshots. To ensure accessibility is continuously maintained, I worked with the Ministry of Education team to integrate axe-core — the same engine that powers axe DevTools — directly into their CI/CD pipeline.
Why axe-core?
- Fast and lightweight — Adds minimal overhead to test runs
- Framework-agnostic — Integrates with Jest, Cypress, Playwright, Selenium, and more
- Same rule engine — Consistent results between local testing and CI/CD
- Configurable — Target specific WCAG levels or rule sets
What this achieved:
Automated accessibility checks now run on every pull request and deployment. Regressions are caught before they reach production — not weeks later when a formal audit is scheduled (which can be delayed due to resourcing, budget cycles, or competing priorities).
The result: the team maintains their high accessibility score continuously, rather than scrambling to fix issues before each audit.
Example integration (Cypress):
import 'cypress-axe';
describe('Accessibility', () => {
beforeEach(() => {
cy.visit('/');
cy.injectAxe();
});
it('should have no critical accessibility violations', () => {
cy.checkA11y(null, {
includedImpacts: ['critical', 'serious']
});
});
});__________
Test 4 — Non-HTML Links
📌 Overview
When linking to non-HTML files (PDFs, Word documents, videos, spreadsheets), users need advance warning about the file type and size. This helps users make informed decisions about downloading content and ensures those using assistive technology aren't surprised by unexpected behaviour.
"When a web page includes a link to a non-HTML file, that link must be accompanied by information indicating the file's format and size." — NZ Web Usability Standard
🌐 WCAG Coverage
- 2.4.4 Link Purpose (In Context) — Level A
- 3.2.5 Change on Request — Level AAA
📋 Steps
- Identify all non-HTML links on the page:
- Use browser DevTools to search for file extensions:
.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.mp3,.mp4,.zip,.csv - In DevTools Console, run:
- Use browser DevTools to search for file extensions:
document.querySelectorAll('a[href$=".pdf"], a[href$=".doc"], a[href$=".docx"], a[href$=".xls"], a[href$=".xlsx"], a[href$=".zip"], a[href$=".mp4"]').forEach(a => console.log(a.href, a.textContent));- For each non-HTML link, verify:
- File format is indicated — Either in the link text, adjacent text, or via an icon with appropriate alt text
- File size is provided — Approximate size in KB or MB
- Link opens predictably — Either downloads or opens in new tab with warning
- Check link text is descriptive:
- ✅ Good: "Annual Report 2024 (PDF, 2.4MB)"
- ❌ Bad: "Click here to download"
- Verify new window/tab behaviour:
- If links open in a new tab, ensure this is indicated
- Check for
target="_blank"and ensure users are warned
✅ Pass Criteria
- All non-HTML links indicate file format
- File size is provided for downloads over 1MB
- Link text is descriptive of the file content
- New window/tab behaviour is communicated
❌ Fail Indicators
- Links to PDFs or documents with no format indication
- Generic link text like "Download" with no context
- Large files with no size warning
- Links that open unexpectedly in new windows
⚠️ Common Issues
- PDF link with no format indicator
Impact: User may not have PDF reader
Fix: Add "(PDF)" to link text - No file size for large download
Impact: User may wait unexpectedly
Fix: Add file size: "(PDF, 15MB)" - Generic "Download" link
Impact: User doesn't know what they're getting
Fix: Describe the document - Unexpected new window
Impact: Disorienting, especially for screen reader users
Fix: Add "(opens in new tab)" or icon with alt text
Example Implementation
<!-- Good example -->
<a href="/reports/annual-2024.pdf">
Annual Report 2024 (PDF, 2.4MB)
</a>
<!-- Good example with icon -->
<a href="/reports/annual-2024.pdf">
Annual Report 2024
<img src="/icons/pdf.svg" alt="PDF document">
<span class="file-size">(2.4MB)</span>
</a>
<!-- Good example for new window -->
<a href="/external-resource.pdf" target="_blank">
External Guidelines (PDF, 500KB, opens in new tab)
</a>__________
Test 5 — Online Forms
📌 Overview
Forms are critical interaction points that must be accessible to all users. This test covers label associations, error handling, input requirements, and overall form usability.
"Feedback for interactions, such as confirming form submission, alerting the user when something goes wrong, or notifying the user of changes on the page need to be provided." — W3C Web Accessibility Initiative
🌐 WCAG Coverage
- 1.3.1 Info and Relationships — Level A
- 2.4.6 Headings and Labels — Level AA
- 3.3.1 Error Identification — Level A
- 3.3.2 Labels or Instructions — Level A
- 3.3.3 Error Suggestion — Level AA
- 3.3.4 Error Prevention (Legal, Financial, Data) — Level AA
📋 Steps
Part A: Label Associations
- For each form field, verify a visible label exists:
- Labels should be adjacent to their field (typically above or to the left)
- Checkboxes and radio buttons: label to the right
- Inspect the code to verify proper association:
- Open DevTools, select the input field
- Check for one of these patterns:
<!-- Pattern 1: for/id association (preferred) -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<!-- Pattern 2: Wrapping label -->
<label>
Email address
<input type="email" name="email">
</label>
<!-- Pattern 3: aria-labelledby -->
<span id="email-label">Email address</span>
<input type="email" aria-labelledby="email-label">- Verify label-input proximity:
- Labels shouldn't be too far from their associated field
- Test by zooming to 200% — labels should remain visually connected
Part B: Instructions and Help Text
- Check that required fields are indicated:
- Visual indicator (asterisk, "required" text)
- Programmatic indicator (
requiredattribute oraria-required="true")
- Verify input format requirements are explained:
- Date formats: "DD/MM/YYYY" or use a date picker
- Password requirements: stated before input, not just on error
- Character limits: shown if applicable
- Check that help text is associated with fields:
<label for="password">Password</label>
<input type="password" id="password" aria-describedby="password-help">
<p id="password-help">Must be at least 8 characters with one number</p>Part C: Error Handling
- Submit the form with empty required fields:
- Errors should be clearly announced
- Error messages should identify which field has the error
- Focus should move to the first error or error summary
- Submit with invalid data (wrong email format, etc.):
- Error messages should explain what's wrong
- Suggestions for fixing should be provided
- Original input should be preserved
- Verify errors are programmatically associated:
<label for="email">Email</label>
<input type="email" id="email" aria-describedby="email-error" aria-invalid="true">
<p id="email-error" role="alert">Please enter a valid email address</p>✅ Pass Criteria
- All form fields have visible, associated labels
- Required fields are indicated visually and programmatically
- Input requirements are stated before the field
- Error messages are clear, specific, and associated with fields
- Form can be completed using keyboard alone
- Error recovery preserves user input
❌ Fail Indicators
- Form fields with no visible label
- Labels only appearing as placeholder text
- Errors that don't explain what went wrong
- Errors only indicated by colour (no text or icon)
- Lost data after validation errors
⚠️ Common Issues
- PDF link with no format indicator
Impact: User may not have PDF reader
Fix: Add "(PDF)" to link text - Placeholder as only label
WCAG: 1.3.1
Fix: Add visible<label>element - Error indicated only by red border
WCAG: 1.4.1
Fix: Add text error message - No error summary
WCAG: 3.3.1
Fix: Add summary at top of form - Generic "Invalid input" error
WCAG: 3.3.3
Fix: Explain what's wrong and how to fix - Required indicator only as asterisk
WCAG: 1.3.1
Fix: Add text "required" or legend explaining asterisk
__________
Test 6 — Keyboard Tabbing
📌 Overview
All interactive elements must be operable via keyboard alone. This test verifies that users who cannot use a mouse can still access all functionality.
"The Tab Key Navigation test is often used to confirm if items are keyboard operable." — W3C WAI
🌐 WCAG Coverage
- 2.1.1 Keyboard — Level A
- 2.1.2 No Keyboard Trap — Level A
- 2.4.3 Focus Order — Level A
- 2.4.7 Focus Visible — Level AA
📋 Steps
- Start at the browser address bar — Click in the URL bar to establish a starting point
- Press Tab to move through the page:
- Each press of Tab should move focus to the next interactive element
- Interactive elements include: links, buttons, form fields, custom widgets
- Document what you observe for each element:
- Focus visible?
Expected Behaviour: Clear visual indicator showing which element has focus - Logical order?
Expected Behaviour: Focus moves left-to-right, top-to-bottom (for LTR languages) - Expected Behaviour: All elements reachable?
Every clickable element receives focus - No elements skipped?
Expected Behaviour: Focus doesn't jump unexpectedly
- Focus visible?
- Test reverse navigation:
- Press
Shift+Tabto move backwards - Should move through elements in reverse order
- Press
- Test specific interactive patterns:
- Links
Expected Keyboard Behaviour:Enteractivates - Buttons
Expected Keyboard Behaviour:EnterorSpaceactivates - Checkboxes
Expected Keyboard Behaviour:Spacetoggles - Radio buttons
Expected Keyboard Behaviour: Arrow keys move between options - Select dropdowns
Expected Keyboard Behaviour: Arrow keys navigate options,Enterselects - Custom dropdowns
Expected Keyboard Behaviour: Should match native behaviour or follow ARIA patterns - Modal dialogs
Expected Keyboard Behaviour:Escapecloses, focus trapped within - Menus
Expected Keyboard Behaviour: Arrow keys navigate,Enterselects,Escapecloses
- Links
- Check for keyboard traps:
- Ensure you can always Tab away from any element
- Pay special attention to: embedded content, video players, rich text editors, modal dialogs
✅ Pass Criteria
- All interactive elements are reachable via Tab
- Focus order matches visual layout
- Focus is always visible
- All functionality works with keyboard alone
- No keyboard traps exist
- Shift+Tab works in reverse order
❌ Fail Indicators
- Interactive elements skipped when tabbing
- Focus disappears or becomes invisible
- Focus order doesn't match visual order
- Can't escape from a widget (keyboard trap)
- Mouse-only functionality (hover-triggered without keyboard alternative)
- Custom widgets that don't respond to expected keys
⚠️ Common Issues
- Can't reach button
WCAG: 2.1.1
Cause:<div>used instead of<button>
Fix: Use semantic HTML or addtabindex="0" - Focus trapped in modal
WCAG: 2.1.2
Cause: No escape key handler
Fix: AddEscapekey listener - Wrong focus order
WCAG: 2.4.3
Cause: CSS changes visual position
Fix: Adjust DOM order or usetabindex - Focus invisible
WCAG: 2.4.7
Cause:outline: nonein CSS
Fix: Provide visible focus style - Hover menu inaccessible
WCAG: 2.1.1
Cause: No keyboard trigger
Fix: Add keyboard activation
💡 Tips
- Don't use
tabindexvalues greater than 0 — they create confusing focus order - Test with CSS disabled to see natural DOM order
- Check that focus styles have sufficient contrast (3:1 minimum against background)
__________
Test 7 — Keyboard Focus
📌 Overview
Focus states must be clearly visible so keyboard users know which element is currently active. This test specifically evaluates the visibility and clarity of focus indicators.
"Focus states let users know which element they're currently on and is ready to be interacted with." — Material Design Guidelines
🌐 WCAG Coverage
- 2.4.7 Focus Visible — Level AA
- 2.4.11 Focus Not Obscured (Minimum) — Level AA (WCAG 2.2)
- 2.4.12 Focus Not Obscured (Enhanced) — Level AAA (WCAG 2.2)
- 2.4.13 Focus Appearance — Level AAA (WCAG 2.2)
📋 Steps
- Navigate through all interactive elements using Tab
- For each element, evaluate the focus indicator:
- Visible
Requirement: Focus indicator is perceivable - Contrast
Requirement: At least 3:1 contrast against adjacent colours - Size
Requirement: Large enough to notice (recommendation: 2px+ outline or clear highlight) - Consistency
Requirement: Similar style across all elements - Not obscured
Requirement: Focus indicator not hidden by other content
- Visible
- Test in different contexts:
- Light and dark page sections
- Within cards or containers
- On images or image links
- On buttons with various background colours
- Check focus isn't only colour:
- Users with colour blindness need shape/position changes too
- Good: outline + slight background change
- Bad: only background colour changes
- Verify focus isn't hidden by overlays:
- Scroll while focused on an element — does sticky header cover it?
- Check that focus-triggered content (like dropdowns) doesn't obscure focus
✅ Pass Criteria
- Every interactive element has a visible focus indicator
- Focus indicators have at least 3:1 contrast ratio
- Focus indicator is visible in all page contexts
- Focus indicator is not hidden by other page elements
- Focus uses more than colour alone to indicate state
❌ Fail Indicators
outline: noneoroutline: 0without replacement style- Focus indicator blends into background
- Focus hidden by sticky headers or footers
- Focus only shown as colour change
- Inconsistent focus styles across elements
Testing Focus Contrast
Use a contrast checker to verify focus indicator visibility:
// In DevTools Console: Find elements with outline: none
document.querySelectorAll('*').forEach(el => {
const style = getComputedStyle(el);
if (style.outlineStyle === 'none' || style.outlineWidth === '0px') {
console.log(el, 'may have suppressed focus indicator');
}
});⚠️ Common Issues
outline: nonein reset CSS
Fix: Add custom focus styles::focus-visible { outline: 2px solid #005fcc; }- Low contrast focus ring
Fix: Use a colour with 3:1+ contrast or add a background change - Focus only inside element
Fix: Add outline outside element bounds - Browser default removed
Fix: Create visible custom styles for all states - Focus hidden by sticky nav
Fix: Add scroll margin:scroll-margin-top: 100px;
Example CSS
/* Good focus styles */
:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
/* Alternative with background */
:focus-visible {
outline: 2px solid #000;
background-color: #ffeeba;
}
/* Prevent focus being hidden by sticky header */
:target,
:focus {
scroll-margin-top: 80px;
}__________
Test 8 — Keyboard Skip Links
📌 Overview
Skip links allow keyboard and screen reader users to bypass repetitive content (like navigation) and jump directly to main content. They're essential for efficient page navigation.
"Skip links are typically placed at the beginning of a page to help users 'skip' to the main content without having to tab through additional navigation." — Deque University
🌐 WCAG Coverage
- 2.4.1 Bypass Blocks — Level A
📋 Steps
- Load the page and immediately press Tab (once or twice)
- Look for a skip link to appear:
- It should be the first or second focusable element
- Common labels: "Skip to main content", "Skip to content", "Skip navigation"
- May be visually hidden until focused
- Press Enter/Return on the skip link
- Verify the skip link works correctly:
- Target exists
- Expected behaviour: Link jumps to the main content area
- Focus moves
Expected behaviour: Focus moves to the target (not just scrolling) - Target is focusable
Expected behaviour: The target element can receive focus (tabindex="-1"if non-interactive) - Next Tab works
Expected behaviour: Pressing Tab again moves to the first link/button in main content
- Test multiple skip links (if present):
- Some sites have multiple: "Skip to content", "Skip to search", "Skip to footer"
- Verify each works correctly
- Verify visibility when focused:
- Skip link should become visible when it receives focus
- Should have sufficient contrast when visible
✅ Pass Criteria
- Skip link is available as first/second focusable element
- Skip link has descriptive text
- Activating skip link moves focus to main content
- Skip link is visible when focused
- Subsequent Tab moves into main content (not back to navigation)
❌ Fail Indicators
- No skip link present
- Skip link goes to wrong location
- Skip link only scrolls (doesn't move focus)
- Skip link not visible when focused
- After skipping, Tab returns to header navigation
Implementation Check
<!-- Good implementation -->
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header><!-- navigation --></header>
<main id="main-content" tabindex="-1">
<!-- main content -->
</main>
</body>
<style>
.skip-link {
position: absolute;
left: -9999px;
z-index: 999;
padding: 1em;
background: #000;
color: #fff;
}
.skip-link:focus {
left: 50%;
transform: translateX(-50%);
top: 0;
}
</style>⚠️ Common Issues
- No skip link
Impact: Users must tab through all nav items
Fix: Add skip link as first element - Skip link target missing
tabindex="-1"Impact: Focus doesn't move, only scrolls
Fix: Addtabindex="-1"to target - Skip link permanently hidden
Impact: Users can't see where they're going
Fix: Make visible on focus - Multiple competing skip links
Impact: Confusing, which to use?
Fix: Consolidate or clearly differentiate - Skip link after nav
Impact: Defeats purpose
Fix: Move to very start of body
__________
Test 9 — Screen Reader
📌 Overview
Screen readers convert visual content to audio or braille output. Testing with a screen reader reveals issues that automated tools cannot detect, such as reading order problems, unclear link purposes, and inadequate alternative text.
"Screen readers can help you identify problems with reading order, table markup, form elements, and many other aspects of accessibility." — Deque University
🌐 WCAG Coverage
Verifies proper implementation of:
- 1.1.1 Non-text Content — Level A
- 1.3.1 Info and Relationships — Level A
- 1.3.2 Meaningful Sequence — Level A
- 2.4.4 Link Purpose — Level A
- 4.1.2 Name, Role, Value — Level A
Screen Reader Options
- macOS/iOS
Screen Reader: VoiceOver
Cost: Free (built-in)
Mac/iPhone users - Windows
Screen Reader: NVDA
Cost: Free
Best For: Best For: Comprehensive testing - Windows
Screen Reader: JAWS
Cost: Paid
Best For: Enterprise/compliance - ChromeOS
Screen Reader: ChromeVox
Cost: Free (built-in)
Best For: Chrome/Chromebook users
📋 Steps (Using VoiceOver on Mac)
- Enable VoiceOver:
- Press
Cmd + F5(orCmd + Fn + F5on laptops) - VoiceOver will start reading the current window
- Press
- Learn basic navigation actions:
- Stop speaking
Command:Ctrl - Read next item
Command:Ctrl + Alt + → - Read previous item
Command:Ctrl + Alt + ← - Interact with element
Command:Ctrl + Alt + Space - Enter a group (like a list)
Command:Ctrl + Alt + Shift + ↓ - Exit a group
Command:Ctrl + Alt + Shift + ↑ - Jump to next heading
Command:Ctrl + Alt + Cmd + H - Jump to next link
Command:Ctrl + Alt + Cmd + L - Open rotor (navigation menu)
Command:Ctrl + Alt + U
- Stop speaking
- Test the page:
- Listen to the page title announcement
- Page title should be announced when page loads
- Navigate by headings
- Use
Ctrl + Alt + Cmd + Hto jump through headings - Heading hierarchy should make sense
- No headings should be skipped (H1 → H3 without H2)
- Use
- Listen to link announcements
- Links should make sense out of context
- Avoid "click here", "read more" without additional context
- Check images
- Decorative images should be skipped
- Informative images should have meaningful alt text
- Complex images (charts, diagrams) should have detailed descriptions
- Test forms
- Form fields should announce their labels
- Required fields should be indicated
- Error messages should be announced
- Check tables
- Table headers should be announced with data cells
- Table should not be used for layout
- Test interactive components
- Buttons should announce their purpose
- Expandable items should announce their state (expanded/collapsed)
- Modal dialogs should trap focus and announce their content
- Listen to the page title announcement
📋 Steps (Using NVDA on Windows)
- Download and install NVDA from nvaccess.org
- Learn basic navigation actions:
- Stop speaking
Command:Ctrl - Read next item
Command:↓orTab - Read previous item
Command:↑orShift + Tab - Activate element
Command:EnterorSpace - Jump to next heading
Command:H - Jump to next landmark
Command:D - List all headings
Command:NVDA + F7
- Stop speaking
- Follow the same testing checklist as VoiceOver above
✅ Pass Criteria
- Page title is announced on load
- Heading hierarchy is logical and complete
- All images have appropriate alternative text (or are marked decorative)
- Links make sense out of context
- Form fields have associated labels that are announced
- Tables announce headers with data
- Interactive components announce their state
- Reading order matches visual order
- No content is skipped or repeated unexpectedly
❌ Fail Indicators
- Page title missing or generic ("Home" on every page)
- Headings skipped (H1 to H3 with no H2)
- Images announced as "image" with no description
- Links announced as "link" or "click here"
- Form fields have no announced label
- Tables read as a confusing stream of data
- State changes not announced (expanded, checked, etc.)
- Content read in wrong order
⚠️ Common Issues
- Missing alt text
What You Hear: "Image" or filename
Fix: Add descriptive alt attribute - Generic link text
What You Hear: "Link: read more"
Fix: Make link text descriptive or addaria-label - Unlabelled form field
What You Hear: "Edit text"
Fix: Associate label withfor/id - Skipped heading level
What You Hear: H1, H3 announced
Fix: Use sequential heading levels - Table without headers
What You Hear: Just cell content
Fix: Add<th>elements withscope - Button with no text
What You Hear: "Button"
Fix: Add visible text oraria-label
__________
Test 10 — Zoom 200%
📌 Overview
Users with low vision often zoom their browser to 200% or more. Content must remain usable at this zoom level without horizontal scrolling or content being cut off.
"Visually rendered text can be scaled successfully so that it can be read directly by people with mild visual disabilities, without requiring the use of assistive technology such as a screen magnifier." — WCAG Understanding 1.4.4
🌐 WCAG Coverage
- 1.4.4 Resize Text — Level AA
- 1.4.10 Reflow — Level AA (WCAG 2.2)
📋 Steps
- Set browser zoom to 200%:
- Chrome/Edge:
Ctrl/Cmd + +(plus key) or Settings > Zoom - Verify the zoom level shows 200% in browser controls
- Chrome/Edge:
- Check text scaling:
- All text should scale proportionally
- Text should not be cut off or overflow containers
- Text should not overlap other elements
- Check for horizontal scrolling:
- At 200% zoom on a 1280px wide screen, content should reflow to fit
- There should be no horizontal scrollbar (except for specific content like data tables)
- Verify functionality:
- All buttons and links remain clickable
- Forms remain usable
- Menus and dropdowns still work
- Modal dialogs fit on screen
- Check specific elements:
- Navigation
Expected at 200%: Should collapse to mobile menu or wrap gracefully - Cards/tiles
Expected at 200%: Should stack vertically or reduce columns - Tables
Expected at 200%: May scroll horizontally (acceptable) but controls should be visible - Images
Expected at 200%: Should scale down or remain within viewport - Text
Expected at 200%: Readable, not truncated withoverflow: hidden
- Navigation
- Test at additional zoom levels:
- 150% — Should work smoothly
- 400% — Content should still be usable (WCAG 2.2 requirement)
✅ Pass Criteria
- All text scales to 200% without loss of content
- No horizontal scrolling required (except for complex data tables)
- All functionality remains accessible
- Content doesn't overlap or become obscured
- Page reflows responsively
❌ Fail Indicators
- Text cut off by fixed-height containers
- Horizontal scrollbar appears at 200% zoom
- Elements overlap making content unreadable
- Functionality breaks (can't submit forms, access menus)
- Text becomes too small relative to containers
- Content disappears or becomes hidden
⚠️ Common Issues
- Text overflow hidden
Cause:overflow: hiddenon fixed-height container
Fix: Usemin-heightoroverflow: auto - Horizontal scroll
Cause: Fixed-width containers
Fix: Use relative units (%, rem, vw) - Overlapping content
Cause: Absolute positioning
Fix: Use flexbox/grid for layout - Truncated navigation
Cause: Not enough space
Fix: Implement responsive nav/hamburger menu - Tiny touch targets
Cause: Fixed pixel sizes
Fix: Use relative sizing, min 44×44px
💡 Tips
- Test on a standard desktop resolution (1280×720 or 1920×1080)
- Also test browser text-only zoom (some browsers offer this separately)
- Check both Chrome and Firefox — they handle zoom slightly differently
- Test in combination with narrow viewport (simulates high zoom on smaller screen)
__________
Test 11 — Responsive Web
📌 Overview
Responsive design ensures content adapts to different viewport sizes and orientations. This test verifies that the website works across desktop, tablet, and mobile viewport sizes.
"Use responsive design to adapt the display to different zoom states and viewport sizes, such as on mobile devices and tablets." — W3C WAI Designing Tips
🌐 WCAG Coverage
- 1.3.4 Orientation — Level AA (WCAG 2.2)
- 1.4.4 Resize Text — Level AA
- 1.4.10 Reflow — Level AA (WCAG 2.2)
📋 Steps
- Open Chrome DevTools (
Ctrl/Cmd + Shift + I) - Enable device toolbar (
Ctrl/Cmd + Shift + Mor click the device icon) - Test at standard breakpoints/Viewports:
- Mobile portrait
Device Type: Phone
Common Width: 320px, 375px, 414px - Mobile landscape
Device Type: Phone
Common Width: 568px, 667px, 896px - Tablet portrait
Device Type: iPad
Common Width: 768px
Tablet landscape
Device Type: iPad
Common Width: 1024px - Desktop
Device Type: Laptop
Common Width: 1280px, 1440px - Large desktop
Device Type: Monitor
Common Width: 1920px+
- Mobile portrait
- At each breakpoint, verify: Content accessibility:
- All content is visible and readable
- No content is cut off or hidden
- Text doesn't extend beyond viewport
- Navigation:
- Menu is accessible (hamburger menu works on mobile)
- All navigation items remain reachable
- Dropdowns/submenus function correctly
- Interactive elements:
- Touch targets are at least 44×44 CSS pixels
- Buttons and links are easily tappable
- Forms remain usable
- Layout:
- Content reflows logically
- Multi-column layouts stack appropriately
- Images scale proportionally
- Test orientation:
- Rotate device simulation between portrait and landscape
- Content should adapt — site should not lock to one orientation
- Verify no functionality is lost in either orientation
- Check specific responsive behaviours:
- Data tables
Mobile Behaviour: Horizontally scrollable or reformatted - Long forms
Mobile Behaviour: Single column layout - Image galleries
Mobile Behaviour: Reduced columns - Sidebars
Mobile Behaviour: Move below main content - Video/embeds
Mobile Behaviour: Scale to container width
- Data tables
✅ Pass Criteria
- Content is accessible at all tested viewport sizes
- No horizontal scrolling at mobile widths (320px)
- All functionality works across viewport sizes
- Touch targets meet minimum size requirements
- Orientation changes don't break layout or functionality
- Content remains readable without zooming
❌ Fail Indicators
- Content cut off at narrow viewports
- Horizontal scrolling required
- Navigation unusable on mobile
- Touch targets too small (under 44px)
- Features only work in landscape or portrait
- Text too small to read on mobile
⚠️ Common Issues
- Fixed-width container
Fix: Usemax-widthwith percentage or viewport units - Table doesn't fit
Fix: Add horizontal scroll wrapper or use responsive table pattern - Nav items too cramped
Fix: mplement hamburger/drawer menu - Images overflow
Fix: Addmax-width: 100%; height: auto; - Tiny buttons
Fix: Set minimum dimensions:min-width: 44px; min-height: 44px;
__________
Test 12 — Mobile Chrome
📌 Overview
Testing on actual mobile devices reveals issues that desktop device emulation may miss, including touch interactions, real performance, and native browser behaviours.
Purpose
- Verify touch interactions work correctly
- Test real-world mobile performance
- Check native browser features (address bar, tab switching)
- Identify issues specific to Chrome on Android
📋 Steps
- Set up remote debugging (recommended):
- Enable Developer Options on Android device
- Enable USB Debugging
- Connect device via USB
- In Chrome desktop, navigate to
chrome://inspect - Find your device and click "Inspect"
- Or test directly on device:
- Navigate to your test page on mobile Chrome
- Test touch interactions:
- Tap
What to Test: Links and buttons activate correctly - Double-tap
What to Test: Doesn't cause unexpected zoom - Swipe
What to Test: Carousels, galleries scroll correctly - Pinch-zoom
What to Test: Page zooms without breaking layout - Long-press
What to Test: Context menus work (if applicable)
- Tap
- Verify touch target sizes:
- Interactive elements should be at least 44×44px
- Adequate spacing between targets (no accidental taps)
- Test with Chrome accessibility features:
- Enable TalkBack (Android screen reader) temporarily
- Verify focus indicators are visible
- Check that custom widgets work with TalkBack
- Check browser-specific issues:
- Address bar shows/hides correctly when scrolling
- Fixed headers/footers don't overlap content
- Form inputs don't zoom page unexpectedly
- Keyboards don't obscure form fields
- Test performance:
- Page loads in reasonable time on mobile network
- Interactions feel responsive
- Animations run smoothly
✅ Pass Criteria
- All content accessible via touch
- Touch targets are adequately sized and spaced
- No unexpected zooming or scrolling
- TalkBack can navigate the page
- Performance is acceptable on mobile networks
- Fixed elements don't obscure content
❌ Fail Indicators
- Buttons too small to tap accurately
- Interactive elements too close together
- Hover-only content inaccessible
- Page requires horizontal scrolling
- Slow/janky scrolling or animations
- Keyboard covers input fields
⚠️ Common Issues
- Inputs zoom page on focus
Fix: Add<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">and use minimum 16px font - Fixed header covers content
Fix: Addscroll-padding-topor target focus offsets - Hover menus don't work
Fix: Add touch/click activation - Touch events don't fire
Fix: Usetouchstart/clickor pointer events
__________
Test 13 — Mobile Safari
📌 Overview
Safari on iOS has unique behaviours and rendering quirks that differ from Chrome. Testing on Safari ensures iOS users have equal access.
Purpose
- Test iOS-specific behaviours
- Verify VoiceOver compatibility
- Check Safari-specific CSS/JS issues
- Test iOS native features integration
📋 Steps
- Test on a physical iOS device (preferred):
- Use Safari browser on iPhone/iPad
- Or use Safari's Responsive Design Mode (Mac only):
- Safari > Develop > Enter Responsive Design Mode
- Select iOS device from dropdown
- Test the same interactions as Mobile Chrome:
- Touch targets (44×44px minimum)
- Gestures (tap, swipe, pinch-zoom)
- Orientation changes
- Test VoiceOver (iOS screen reader):
- Enable: Settings > Accessibility > VoiceOver > On
- Or use Siri: "Turn on VoiceOver"
- Basic VoiceOver gestures:
- Swipe right
Action: Next element - Swipe left
Action: Previous element - Double-tap
Action: Activate element - Three-finger swipe
Action: Scroll - Two-finger tap
Action: Stop speaking
- Swipe right
- Verify VoiceOver navigation:
- All content is reachable
- Reading order is logical
- Form fields announce labels
- Buttons announce their purpose
- State changes are announced
- Check Safari-specific issues:
- Position: fixed
What to Check: May jump or flicker when scrolling - 100vh
What to Check: May not account for Safari UI; use100svh - Date inputs
What to Check: Native date picker works correctly - Custom select styling
What to Check: Verify native picker still accessible - Smooth scroll
What to Check: May not work; usescroll-behaviorcarefully
- Position: fixed
- Test form inputs:
- Input types show correct keyboards (email, phone, number)
- Date/time pickers are accessible
- Autocomplete works appropriately
✅ Pass Criteria
- Full VoiceOver compatibility
- All content and functionality accessible
- No Safari-specific rendering bugs
- Native iOS features work correctly
- Touch interactions behave as expected
❌ Fail Indicators
- VoiceOver can't access content
- Layout breaks compared to Chrome
- Fixed elements misbehave
- Forms difficult to complete
- Custom widgets don't announce state to VoiceOver
⚠️ Common Issues
100vhtoo tall
Fix: Use100svhor100dvh(small/dynamic viewport)- Input zoom on focus
Fix: Ensure inputs are at least 16px font size - Button styling looks wrong
Fix: Add-webkit-appearance: none;and restyle - Scrolling momentum issues
Fix: Add-webkit-overflow-scrolling: touch; - VoiceOver doesn't announce updates
Fix: Usearia-liveregions
__________
Test 14 — Print Styles
📌 Overview
Some users print web pages for offline reading, record-keeping, or sharing. Print stylesheets should ensure the main content prints clearly without unnecessary elements.
"It is required that each web page's main content be printable on standard sheets of paper." — NZ Web Usability Standard
🌐 WCAG Coverage
While not explicitly a WCAG requirement, print accessibility relates to:
- 1.1.1 Non-text Content — Alt text for images in print
- 1.4.1 Use of Colour — Information shouldn't depend solely on colour
- 1.4.3 Contrast — Text should be readable when printed
📋 Steps
- Open the page in your browser
- Access print preview:
- Press
Ctrl/Cmd + P - Or File > Print
- Press
- Review the print preview for: ✅ Elements that should print:
- Main content
Article text, primary information - Headings
Maintain document structure - Data tables
Essential tabular data - Images (if meaningful)
With alt text available - Links (URLs displayed)
Optionally show URL in parentheses
- Main content
- Elements that should ❌ NOT print:
- Navigation menus
Not useful on paper - Sidebar widgets
Usually not essential - Search forms
Non-functional on paper - Video/audio players
Can't play on paper - Advertisements
Waste of ink/paper - Decorative images
Background images, icons - Cookie banners
Not relevant - Chat widgets
Non-functional
- Navigation menus
- Check text formatting:
- Text should be black on white (conserves ink, maximises contrast)
- Font size should be readable (11-12pt minimum)
- Line length appropriate for page width
- No text cut off at page breaks
- Check link handling:
- Links should be identifiable (underlined or URL shown)
- Long URLs shouldn't break layout
- Consider showing URLs after link text:
For more information, see the guidelines (https://example.com/guidelines)- Test page breaks:
- Headings shouldn't appear alone at bottom of page
- Tables and images shouldn't break awkwardly
- Key content groups stay together
- Verify with actual print (optional):
- Print a few sample pages
- Check for ink waste (large coloured backgrounds)
- Verify readability on paper
✅ Pass Criteria
- Main content prints clearly
- Navigation and non-essential elements hidden
- Text is black on white or high contrast
- Links are identifiable
- Page breaks occur at logical points
- No content cut off
❌ Fail Indicators
- Navigation prints, wasting pages
- White text on coloured backgrounds
- Content cut off at edges
- Links indistinguishable from text
- Page breaks mid-sentence or mid-row
- Background images print, wasting ink
CSS Print Stylesheet Checklist
@media print {
/* Hide non-essential elements */
nav,
header,
footer,
aside,
.sidebar,
.navigation,
.search-form,
.social-share,
.comments,
.related-articles,
.cookie-banner,
.chat-widget,
.video-player,
.advertisement {
display: none !important;
}
/* Reset colours for readability */
body {
color: #000 !important;
background: #fff !important;
}
/* Ensure text is readable */
body {
font-size: 12pt;
line-height: 1.5;
}
/* Show link URLs */
a[href]:after {
content: " (" attr(href) ")";
font-size: 0.9em;
color: #666;
}
/* Don't show URL for internal/anchor links */
a[href^="#"]:after,
a[href^="javascript"]:after {
content: "";
}
/* Prevent orphan headings */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
}
/* Keep images with captions */
figure, img {
page-break-inside: avoid;
}
/* Keep tables together where possible */
table, tr {
page-break-inside: avoid;
}
}⚠️ Common Issues
- Navigation prints
Fix: Add@media print { nav { display: none; } } - White text disappears
Fix: Reset colours in print stylesheet - Background images print
Fix: Setbackground: nonein print styles - No URL shown for links
Fix: Use:afterpseudo-element to show href - Page breaks mid-content
Fix: Usepage-break-inside: avoid
__________
WCAG Quick Reference
Priority Levels
- A
Meaning: Essential
Requirement: Minimum accessibility, must implement - AA
Meaning: Standard
Requirement: Required for most regulations (ADA, Section 508, EN 301 549) - AAA
Meaning: Enhanced
Requirement: Best practice, may not be achievable for all content
Key Success Criteria Reference
- 1.1.1 Non-text Content
Level: A
Summary: Images have text alternatives - 1.2.1 Audio/Video (Prerecorded)
Level: A
Summary: Captions and audio descriptions - 1.3.1 Info and Relationships
Level: A
Summary: Structure conveyed programmatically - 1.3.2 Meaningful Sequence
Level: A
Summary: Reading order makes sense - 1.4.1 Use of Colour
Level: A
Summary: Colour not sole means of conveying info - 1.4.3 Contrast (Minimum)
Level: AA
Summary: 4.5:1 for text, 3:1 for large text - 1.4.4 Resize Text
Level: AA
Summary: Text resizes to 200% without loss - 1.4.10 Reflow
Level: AA
Summary: No horizontal scroll at 320px width - 2.1.1 Keyboard
Level: A
Summary: All functionality via keyboard - 2.1.2 No Keyboard Trap
Level: A
Summary: Focus can always be moved away - 2.4.1 Bypass Blocks
Level: A
Summary: Skip navigation mechanism - 2.4.3 Focus Order
Level: A
Summary: Logical focus sequence - 2.4.4 Link Purpose
Level: A
Summary: Link text is descriptive - 2.4.6 Headings and Labels
Level: AA
Summary: Headings describe topic/purpose - 2.4.7 Focus Visible
Level: AA
Summary: Keyboard focus is visible - 3.1.1 Language of Page
Level: A
Summary: Page language is specified - 3.3.1 Error Identification
Level: A
Summary: Errors are described in text - 3.3.2 Labels or Instructions
Level: A
Summary: Form fields have labels - 4.1.1 Parsing
Level: A
Summary: Valid HTML (deprecated in WCAG 2.2) - 4.1.2 Name, Role, Value
Level: A
Summary: Custom widgets have accessible names
References
Standards and Guidelines
Testing Tools
Learning Resources
- W3C Web Accessibility Initiative (WAI)
- WebAIM
- Deque University
- A11y Project
- Accessibility Fundamentals (Google)
Screen Readers
License
This guide is provided as an open resource. Feel free to adapt it for your team's needs with attribution.
__________
🛟 Ready to Go Further?
If this guide has been useful and you'd like expert help auditing your website or application, let's talk — Contact me on LinkedIn. I partner with government, enterprise, and agency teams to deliver end-to-end accessibility audits, remediation advice, and hands-on implementation — ensuring your digital products meet WCAG 2.2 AA and beyond.

