WCAG Compliance — Complete Guide to Web Accessibility Standards
In this tutorial, you'll learn about WCAG Compliance. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
WCAG 2.2 (Web Content Accessibility Guidelines) provides a globally recognized standard for web Accessibility with three conformance levels — A, AA, and AAA — and new success criteria covering focus appearance, accessible authentication, dragging movements, and pointer target spacing.
What You'll Learn
By the end of this guide, you will understand the four POUR principles, the three conformance levels, the new WCAG 2.2 success criteria and what they require, how to evaluate Compliance using automated tools (WAVE, axe, Lighthouse), how to create a valid WCAG conformance claim, and how to build a prioritised remediation workflow for your project.
Why WCAG Compliance Matters
WCAG 2.2 is referenced by laws worldwide — the Americans with Disabilities Act, Section 508, the European Accessibility Act, and many others. Achieving WCAG AA Compliance is the legal benchmark for most organizations. Beyond legal requirements, WCAG Compliance improves SEO, user experience, and brand reputation. At DodaTech, Doda Browser includes an Accessibility checker that scans pages against WCAG criteria in real time, helping developers catch issues during development.
WCAG Compliance Learning Path
flowchart LR
A[Accessibility Overview] --> B[WCAG Compliance Guide]
B --> C[ARIA Guide]
B --> D[Keyboard Navigation]
B --> E[Color Contrast Guide]
B:::current
classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px
{{< callout type="info" icon="sparkles" >}} Prerequisites: Understanding of the POUR principles from the Accessibility Overview. Basic HTML knowledge. Familiarity with browser DevTools is helpful. {{< /callout >}}
What Is WCAG?
The Web Content Accessibility Guidelines are developed by the World Wide Web Consortium (W3C) through the Web Accessibility Initiative (WAI). WCAG 2.2 was published in October 2023 as the latest version, building on WCAG 2.1 and 2.0.
WCAG is organized around four principles known by the acronym POUR:
| Principle | Meaning | Example Criteria |
|---|---|---|
| Perceivable | Users must perceive the content | Alt text, captions, contrast |
| Operable | Users must operate the interface | Keyboard, focus, enough time |
| Understandable | Users must understand the content | Readable text, predictable behavior |
| Robust | Content works with assistive tech | Semantic HTML, ARIA, parsable code |
WCAG Conformance Levels
Level A — Minimum
Level A is the minimum level of conformance. Failing any Level A criterion means your site is completely inaccessible to some users:
- 1.1.1 Non-text Content — alt text for images
- 2.1.1 Keyboard — all functionality via keyboard
- 2.4.4 Link Purpose (In Context) — links describe their purpose
- 3.3.2 Labels or Instructions — form inputs must have labels
- 4.1.2 Name, Role, Value — custom controls report their role and State
Level AA — The Legal Standard
Level AA is the most common legal benchmark. Most Accessibility lawsuits reference WCAG AA Compliance:
- 1.4.3 Contrast (Minimum) — 4.5:1 ratio for normal text
- 2.4.7 Focus Visible — keyboard focus indicator must be visible
- 3.3.3 Error Suggestion — error messages suggest fixes
- 4.1.3 Status Messages — status changes announced to assistive tech
Level AAA — The Highest Standard
Level AAA is the highest conformance level. Not all content can meet AAA, and it is not typically required by law:
- 1.4.6 Contrast (Enhanced) — 7:1 ratio
- 2.4.10 Section Headings — organize content with headings
- 3.1.5 Reading Level — advanced content can have a simplified version
New in WCAG 2.2
2.4.11 Focus Appearance (AA)
The focus indicator must be at least as large as a 2-pixel thick perimeter of the element with a contrast ratio of at least 3:1 against the unfocused State:
/* ✅ Good — meets Focus Appearance */
button:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
/* ❌ Bad — fails Focus Appearance */
button:focus {
outline: 1px dotted #ccc;
outline-offset: 0;
}
3.3.7 Accessible Authentication (AA)
Authentication must not rely on cognitive function tests requiring the user to remember or transcribe information. Biometrics, security keys, and paste-supporting password fields are acceptable:
<!-- ✅ Good — allow password manager paste -->
<label for="password">Password</label>
<input type="password" id="password" name="password"
autocomplete="current-password">
<!-- ✅ Good — offer passkey option -->
<button type="button" onclick="webAuthnLogin()">
Sign in with Passkey
</button>
<!-- ❌ Bad — cognitive test (remembering a password is exempt,
but transcription tasks like "type the third word" are not) -->
2.5.8 Dragging Movements (AA)
If an operation requires dragging, there must be an alternative single-pointer method:
function initAccessibleDragDrop(container) {
const items = container.querySelectorAll('.draggable');
items.forEach(item => {
item.setAttribute('draggable', 'true');
// Single-click alternative
item.addEventListener('click', function(e) {
if (this.dataset.selected === 'true') {
placeItem(this, getTargetPosition(e));
this.dataset.selected = 'false';
} else {
selectItem(this);
this.dataset.selected = 'true';
}
});
});
}
2.5.7 Pointer Target Spacing (AA)
Pointer targets must be at least 24 by 24 CSS pixels with sufficient spacing from adjacent targets:
/* ✅ Good — meets 24 by 24 minimum */
.nav-link {
display: inline-block;
padding: 12px 16px;
min-width: 24px;
min-height: 24px;
}
/* ✅ Good — spacing between targets */
.menu-item + .menu-item {
margin-inline-start: 8px;
}
/* ❌ Bad — tiny targets touching each other */
.tab {
padding: 4px 8px;
margin: 0;
}
Evaluating Compliance
Automated Tools
# axe-core CLI — run on any URL
npx axe http://localhost:3000 --save report.json
# Pa11y CI — configure and run
npx pa11y-ci --config .pa11yci.json
# Lighthouse — built into Chrome DevTools
// Programmatic WCAG audit
const { axe } = require('axe-core');
const { JSDOM } = require('jsdom');
async function checkWCAG(html) {
const { window } = new JSDOM(html);
const results = await axe.run(window.document);
return results.violations;
}
checkWCAG(`<html><body><img src="photo.jpg"><button>Click</button></body></html>`)
.then(violations => {
console.log(`Found ${violations.length} violations`);
violations.forEach(v => console.log(` [${v.impact}] ${v.help} (${v.tags.filter(t => t.startsWith('wcag')).join(', ')})`));
});
Expected output:
Found 2 violations
[critical] Images must have alternate text (wcag2a, wcag111)
[serious] Document must have one main landmark (wcag2a, wcag412)
Manual Testing Checklist
| Check | How to Test | WCAG Criterion |
|---|---|---|
| Keyboard navigation | Tab through all elements | 2.1.1 Keyboard |
| Focus visibility | Watch focus indicator while tabbing | 2.4.7 Focus Visible, 2.4.11 Focus Appearance |
| Screen reader | NVDA or VoiceOver reading order | 4.1.2 Name, Role, Value |
| Zoom to 400 percent | Resize browser to 400 percent | 1.4.4 Resize Text |
| Color contrast | Use contrast checking tool | 1.4.3 Contrast Minimum |
| Touch targets | Inspect with DevTools | 2.5.8 Pointer Target Spacing |
flowchart TD
A[Accessibility Audit] --> B[Automated Scan]
A --> C[Manual Testing]
A --> D[Screen Reader Test]
A --> E[User Testing]
B --> F[Violation List]
C --> G[Keyboard and Focus Issues]
D --> H[Screen Reader UX Issues]
E --> I[Real-World Barriers]
F --> J[Prioritise and Remediate]
G --> J
H --> J
I --> J
Conformance Claims
A WCAG conformance claim is a public statement that your pages meet WCAG requirements:
<div aria-label="Accessibility conformance statement">
<p>
This website conforms to
<a href="https://www.w3.org/TR/WCAG22/">WCAG 2.2</a>
at Level AA. Last reviewed: June 2026.
</p>
<p>
Evaluation method:
<a href="https://www.w3.org/WAI/eval/conformance.html">WCAG-EM</a>.
</p>
</div>
{
"@context": "https://schema.org",
"@type": "WebPage",
"accessibilityFeature": ["alternativeText", "longDescription", "structuredNavigation"],
"accessibilityHazard": ["noFlashingHazard"],
"accessibilityAPI": "ARIA",
"accessibilityControl": ["fullKeyboardControl", "fullMouseControl"],
"accessMode": ["textual", "visual"],
"accessModeSufficient": ["textual", "visual"]
}
Remediation Workflow
- Critical (Level A failures) — Fix immediately. Users are blocked entirely.
- Serious (Level AA failures) — Fix within the Sprint. Users are significantly impacted.
- Moderate (Level AA best practices) — Fix within the next Sprint. Users are inconvenienced.
- Minor (Level AAA suggestions) — Add to backlog. Enhancements for power users.
git checkout -b fix/wcag-critical-issues
git add public/images/
git commit -m "fix(a11y): Add alt text to 15 images
- Descriptive alt for 12 informative images
- Empty alt for 3 decorative images
- WCAG SC 1.1.1 Non-text Content"
git add src/styles/
git commit -m "fix(a11y): Improve focus indicators
- 3px blue outline on :focus-visible
- 3:1 contrast ratio for focus states
- WCAG SC 2.4.7, 2.4.11"
Common Compliance Mistakes
1. Relying Only on Automated Tools
A perfect Lighthouse score does not mean WCAG Compliance. Automated tools catch roughly 30 percent of criteria.
2. Confusing WCAG Levels
Passing all Level A criteria does not mean you pass Level AA. AA includes A plus additional criteria. Conformance is hierarchical.
3. Missing Conformance Documentation
Simply adding an Accessibility badge to your footer does not constitute a valid conformance claim. You need documented evaluation methodology, scope, and date.
4. Ignoring New WCAG 2.2 Criteria
Focus Appearance, Accessible Authentication, Dragging Movements, and Pointer Target Spacing are new in 2.2 and are frequently missed in audits.
5. Not Testing on Mobile
WCAG applies to all content on all devices. Mobile-specific issues — touch targets, viewport zoom, orientation — are commonly overlooked.
6. Making Changes Without Regression Testing
Fixing one Accessibility issue can introduce another. Always re-test after changes, ideally with automated CI checks.
7. Not Involving Users
The most reliable way to know if your site is accessible is to test with real users who rely on assistive technologies.
Practice Questions
1. What are the three conformance levels of WCAG 2.2? Level A (minimum), Level AA (legal standard), Level AAA (highest). Most legal requirements target Level AA.
2. What is new in WCAG 2.2? Focus Appearance (AA), Accessible Authentication (AA), Dragging Movements (AA), and Pointer Target Spacing (AA) are the major new success criteria.
3. Why can you not rely solely on automated Accessibility Testing? Automated tools catch roughly 30 percent of issues. They miss contextual problems like meaningful alt text, keyboard navigation logic, and screen reader announcement quality.
4. What does a valid WCAG conformance claim require? Documentation of the evaluation method (WCAG-EM), scope of evaluated content, date of evaluation, WCAG version, and conformance level.
5. Challenge: Run axe-core on a single page of a site you manage. Document all violations by WCAG success criterion and level. Fix the three most critical issues and document how you tested the fix.
Real-World Task
Create a WCAG Compliance matrix for your project. List all 86 success criteria. Mark each as Pass, Fail, or Not Applicable. Include the testing method used (automated tool, manual check, screen reader test). Create a remediation plan prioritised by conformance level.
FAQ
Try It Yourself
Build a WCAG 2.2 automated audit script:
// wcag-audit.js
const { JSDOM } = require('jsdom');
async function wcagAudit(HTML) {
const { window } = new JSDOM(HTML);
const doc = window.document;
const issues = [];
// SC 1.1.1 — Images without alt text
doc.querySelectorAll('img:not([alt])').forEach(img => {
issues.push({ sc: '1.1.1', level: 'A', element: img.outerHTML.substring(0, 60), message: 'Image missing alt attribute' });
});
// SC 3.3.2 — Inputs without labels
doc.querySelectorAll('input:not([type="hidden"]):not([aria-label]):not([aria-labelledby])').forEach(input => {
const id = input.getAttribute('id');
if (!id || !doc.querySelector(`label[for="${id}"]`)) {
issues.push({ sc: '3.3.2', level: 'A', element: input.outerHTML.substring(0, 60), message: 'Input without associated label' });
}
});
// SC 3.1.1 — Missing lang attribute
if (!doc.documentElement.getAttribute('lang')) {
issues.push({ sc: '3.1.1', level: 'A', element: '<HTML>', message: 'Missing lang attribute' });
}
return issues;
}
const HTML = `<!DOCTYPE HTML><HTML><head><title>Test</title></head><body>
<img src="photo.jpg">
<input type="text">
</body></HTML>`;
wcagAudit(HTML).then(issues => {
console.log(`Found ${issues.length} issues:`);
issues.forEach(i => console.log(` [${i.level}] SC ${i.sc}: ${i.message}`));
});
Expected output:
Found 3 issues:
[A] SC 1.1.1: Image missing alt attribute
[A] SC 3.3.2: Input without associated label
[A] SC 3.1.1: Missing lang attribute
What's Next
Congratulations on completing the WCAG Compliance guide! Here is where to Go from here:
- Practice daily — Run axe on every page you build
- Build a project — Create a WCAG Compliance dashboard for your team
- Explore related topics — Learn ARIA basics next
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro