Web Accessibility: A Complete Guide
Learn how to build accessible web applications that everyone can use. Comprehensive guide to WCAG standards and best practices.
Why Accessibility Matters
Web accessibility ensures that websites, tools, and technologies are designed and developed so that people with disabilities can use them. But it benefits everyone.
Understanding WCAG
The Web Content Accessibility Guidelines (WCAG) provide a framework for making content more accessible:
Four Principles: POUR
- Perceivable - Information must be presentable to users in ways they can perceive
- Operable - User interface components must be operable
- Understandable - Information and operation must be understandable
- Robust - Content must be robust enough to work with various technologies
Essential Accessibility Practices
Semantic HTML
Use the right HTML elements for the right purpose:
<!-- Good -->
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- Bad -->
<div class="nav">
<div onclick="goHome()">Home</div>
<div onclick="goAbout()">About</div>
</div>
ARIA Labels
Provide context with ARIA attributes:
<button aria-label="Close dialog">
<svg aria-hidden="true">...</svg>
</button>
<nav aria-label="Main navigation">
<!-- Navigation content -->
</nav>
Keyboard Navigation
Ensure all interactive elements are keyboard accessible:
// Trap focus in modal
function trapFocus(element) {
const focusableElements = element.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstFocusable = focusableElements[0];
const lastFocusable = focusableElements[focusableElements.length - 1];
element.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstFocusable) {
lastFocusable.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === lastFocusable) {
firstFocusable.focus();
e.preventDefault();
}
}
});
}
Color Contrast
Ensure sufficient color contrast ratios:
- Normal text: Minimum 4.5:1
- Large text: Minimum 3:1
- UI components: Minimum 3:1
/* Good contrast */
.button {
background: #0066cc;
color: #ffffff;
/* Contrast ratio: 8.59:1 */
}
/* Poor contrast */
.bad-button {
background: #cccccc;
color: #999999;
/* Contrast ratio: 2.51:1 - fails WCAG */
}
Testing Tools
Use these tools to audit accessibility:
- axe DevTools - Browser extension for automated testing
- WAVE - Web accessibility evaluation tool
- Lighthouse - Built into Chrome DevTools
- Screen readers - NVDA (Windows), VoiceOver (Mac), JAWS
- Keyboard testing - Unplug your mouse!
Common Issues to Avoid
Missing Alt Text
<!-- Bad -->
<img src="chart.png">
<!-- Good -->
<img src="chart.png" alt="Bar chart showing 50% increase in sales over Q1">
<!-- Decorative images -->
<img src="decoration.png" alt="" role="presentation">
Poor Focus Indicators
/* Bad - removing focus outline */
button:focus {
outline: none;
}
/* Good - custom focus indicator */
button:focus {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
Form Labels
<!-- Bad -->
<input type="email" placeholder="Email">
<!-- Good -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
Practical Tips
- Use headings properly - Maintain hierarchy (h1, h2, h3)
- Provide skip links - Let users skip to main content
- Make links descriptive - Avoid “click here”
- Caption videos - Provide captions and transcripts
- Test with real users - Include people with disabilities in testing
Accessibility in React
function AccessibleButton({ onClick, children }) {
return (
<button
onClick={onClick}
aria-pressed="false"
className="btn"
>
{children}
</button>
);
}
function AccessibleForm() {
const [email, setEmail] = useState('');
const emailId = useId();
return (
<div>
<label htmlFor={emailId}>Email</label>
<input
id={emailId}
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
aria-required="true"
aria-invalid={!isValidEmail(email)}
/>
</div>
);
}
Legal Requirements
In many countries, web accessibility is legally required:
- USA: Section 508, ADA
- EU: European Accessibility Act
- UK: Equality Act 2010
- Canada: AODA
Non-compliance can result in lawsuits and penalties.
Conclusion
Accessibility is not optional—it’s a fundamental part of web development. By following WCAG guidelines and testing thoroughly, you can create websites that work for everyone. Remember: accessibility benefits all users, not just those with disabilities.