Web Accessibility Best Practices
Web Accessibility Best Practices
Web accessibility means designing and developing websites that can be used by everyone, including people with disabilities. It's not just a nice-to-have feature—it's a legal requirement in many countries and the right thing to do.
Why Accessibility Matters
- Inclusivity: About 15% of the world's population has some form of disability
- Legal compliance: Many countries have laws requiring accessible websites
- Better UX for everyone: Accessible sites are often easier for all users to navigate
- SEO benefits: Many accessibility practices improve search engine rankings
The WCAG Guidelines
The Web Content Accessibility Guidelines (WCAG) provide a framework for making web content accessible. They're organized around four principles, often remembered by the acronym 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 current and future technologies
Semantic HTML
Using the right HTML elements for their intended purpose is the foundation of accessibility.
<!-- Bad: Using divs for everything -->
<div class="header">
<div class="nav">
<div class="nav-item">Home</div>
</div>
</div>
<!-- Good: Using semantic elements -->
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
Keyboard Navigation
Ensure all interactive elements are keyboard accessible.
<!-- Bad: Using a div as a button -->
<div class="button" onclick="submitForm()">Submit</div>
<!-- Good: Using a button element -->
<button type="submit">Submit</button>
Focus Management
Users who navigate with keyboards need to see where they are on the page.
/* Make focus visible */
:focus {
outline: 2px solid #4a90e2;
outline-offset: 2px;
}
/* Don't hide focus on mouse click (bad practice) */
:focus:not(:focus-visible) {
outline: none;
}
/* Style focus-visible for keyboard users */
:focus-visible {
outline: 2px solid #4a90e2;
outline-offset: 2px;
}
Alternative Text for Images
Provide descriptive alt text for images that convey information.
<!-- Informative image needs descriptive alt text -->
<img src="chart.png" alt="Bar chart showing sales increasing 25% in Q4 2022">
<!-- Decorative image should have empty alt -->
<img src="decorative-line.png" alt="">
<!-- Complex images might need extended descriptions -->
<figure>
<img src="complex-diagram.png" alt="System architecture diagram">
<figcaption>
System architecture showing data flow between user interface,
API layer, and database. <a href="diagram-description.html">View detailed description</a>
</figcaption>
</figure>
Color and Contrast
Ensure sufficient color contrast and don't rely solely on color to convey information.
/* Good contrast ratio (at least 4.5:1 for normal text) */
.text {
color: #333; /* Dark gray */
background-color: #fff; /* White */
}
/* Don't rely only on color for links */
a {
color: #0066cc;
text-decoration: underline; /* Visual indicator beyond color */
}
ARIA When Necessary
ARIA (Accessible Rich Internet Applications) attributes can enhance accessibility when HTML alone isn't enough.
<!-- Custom dropdown menu -->
<div role="combobox" aria-expanded="false" aria-controls="dropdown-list">
<button aria-haspopup="listbox">Select an option</button>
<ul id="dropdown-list" role="listbox" hidden>
<li role="option">Option 1</li>
<li role="option">Option 2</li>
</ul>
</div>
<!-- Live region for dynamic content -->
<div aria-live="polite" aria-atomic="true">
<!-- Content that updates dynamically -->
</div>
Remember: No ARIA is better than bad ARIA. Only use ARIA when necessary and ensure you're using it correctly.
Form Accessibility
Forms are often challenging for users with disabilities.
<!-- Accessible form -->
<form>
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email"
aria-describedby="email-hint" required>
<p id="email-hint">We'll never share your email with anyone else.</p>
</div>
<div>
<fieldset>
<legend>Subscription type:</legend>
<div>
<input type="radio" id="monthly" name="subscription" value="monthly">
<label for="monthly">Monthly</label>
</div>
<div>
<input type="radio" id="yearly" name="subscription" value="yearly">
<label for="yearly">Yearly</label>
</div>
</fieldset>
</div>
<button type="submit">Subscribe</button>
</form>
Testing Accessibility
Use a combination of automated and manual testing:
- Automated tools: Lighthouse, axe, WAVE
- Screen reader testing: NVDA, JAWS, VoiceOver
- Keyboard-only navigation: Try using your site without a mouse
- Color contrast checkers: WebAIM Contrast Checker
- User testing: Include people with disabilities in your testing process
Conclusion
Accessibility is not a checklist but a continuous process. By incorporating these practices into your development workflow, you'll create websites that are usable by more people and often provide a better experience for all users.
Remember that accessibility benefits everyone—not just users with permanent disabilities. People with temporary limitations (like a broken arm), situational limitations (like bright sunlight on a screen), or age-related changes all benefit from accessible design.