Accessibility for Developers: How to Build Features That Everyone Can Use
A practical guide for developers on integrating accessibility from design to code — covering WCAG essentials, component patterns, and real-world examples.
Why Accessibility Isn’t Optional
Let’s be honest: accessibility often gets treated like that optional feature you'll add "later" — right after you ship the main functionality and fix all the bugs. But here's the thing: accessibility isn't an extra layer you bolt onto your app. It's not a checkbox you tick after everything else is done. It's a fundamental part of building software that works for everyone.
Most developers I know aren't ignoring accessibility out of neglect. They're just unsure where to start — what tools to use, what to test, or how to integrate it into their workflow without slowing down development.
This article is for those developers.
Understand the Accessibility Foundations
If you’re new to accessibility, start with the WCAG 2.1 Quick Reference. Don’t worry — you don’t have to memorize the entire spec. Focus instead on the four key principles that define accessible experiences:
- Perceivable – Can users see, hear, or otherwise perceive your content?
- Operable – Can users navigate and interact with your interface?
- Understandable – Is your content and behavior predictable and clear?
- Robust – Does your code work with assistive technologies like screen readers or voice input?
During code reviews, start asking these two simple questions:
Can someone using a screen reader understand this?”
“Can someone navigate this with just a keyboard?
These questions alone will uncover a surprising number of issues before they ever reach production.
Start with Accessible Design Choices
Accessibility begins long before code — it starts with design decisions.
When reviewing designs, check for the following:
- Contrast – Text must maintain at least a 4.5:1 contrast ratio against its background. Use tools like WebAIM’s Contrast Checker to verify.
- Heading Hierarchy – Headings should form a logical outline (H1 → H2 → H3). Screen reader users rely on these for navigation.
- Focus Order – Tab through your prototype or build. The focus should move in a predictable, logical order.
- Color Independence – Never rely solely on color to convey meaning. Pair color with icons, text, or ARIA feedback.
Accessible design is just good UX — it reduces friction for everyone.
Build Components That Include Everyone
Once your design supports accessibility, your components need to carry that through.
Here are practical examples for everyday components.
Buttons
// ❌ Bad: No accessible name
<button onClick={handleClick}>
<Icon name="close" />
</button>
// ✅ Good: Clear accessible name
<button onClick={handleClick} aria-label="Close dialog">
<Icon name="close" />
</button>
// ✅ Even better: Visible text when possible
<button onClick={handleClick}>
<Icon name="close" aria-hidden="true" />
<span className="sr-only">Close dialog</span>
</button>
A button should always have a clear label — visible or via
aria-label.
Icons alone aren't enough for screen readers.
Dropdowns
// ❌ Bad: Not keyboard accessible
<div className="dropdown" onClick={toggleDropdown}>
<span>{selectedOption}</span>
<div className="dropdown-menu">
{options.map(option => (
<div key={option.value} onClick={() => selectOption(option)}>
{option.label}
</div>
))}
</div>
</div>
// ✅ Good: Proper ARIA and keyboard support
<div className="dropdown">
<button
aria-expanded={isOpen}
aria-haspopup="listbox"
onClick={toggleDropdown}
onKeyDown={handleKeyDown}
>
{selectedOption}
</button>
<ul
role="listbox"
aria-activedescendant={activeId}
className="dropdown-menu"
>
{options.map(option => (
<li
key={option.value}
role="option"
aria-selected={option.value === selectedValue}
onClick={() => selectOption(option)}
>
{option.label}
</li>
))}
</ul>
</div>
Dropdowns should be fully operable with a keyboard and announce changes to assistive tech.
ARIA roles help convey that structure.
Links
// ❌ Bad: Unclear link text
<a href="/products">Click here</a>
// ✅ Good: Descriptive link text
<a href="/products">View our product catalog</a>
// ✅ Better: Context-aware link text
<p>
Ready to explore our offerings?
<a href="/products">Browse our product catalog</a>
to see what we have available.
</p>
Link text should make sense out of context.
Screen readers often list all links on a page — "Click here" tells them nothing.
Automate Accessibility Testing Early
Don’t wait for manual audits. Automate checks early in development to prevent regressions.
axe-core
Integrate it into your tests — it automatically detects about half of all accessibility issues.
npm install --save-dev @axe-core/react
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('should not have accessibility violations', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
eslint-plugin-jsx-a11y
Add to your ESLint config — it enforces rules like alt text, keyboard focus, and valid ARIA attributes.
npm install --save-dev eslint-plugin-jsx-a11y
// .eslintrc.js
module.exports = {
extends: ['plugin:jsx-a11y/recommended'],
};
Lighthouse
Run accessibility and performance audits automatically in CI/CD pipelines to track improvements over time.
Make Accessibility Part of Everyday Development
Accessibility isn’t a “one-time fix”. It’s part of your team’s definition of done.
Accessibility in Code Reviews and PRs
Include a short checklist in every pull request:
## Accessibility Checklist
- [ ] All images include descriptive alt text
- [ ] Color contrast meets WCAG 2.1 AA
- [ ] Components support full keyboard navigation
- [ ] Screen reader testing completed
- [ ] Focus indicators are visible and consistent
Team Training and Knowledge Sharing
Encourage developers and designers to take turns leading short accessibility sessions — for example, "How screen readers interpret headings" or "Testing with keyboard only".
This keeps accessibility top of mind without slowing development.
Accessibility Is Just Good Engineering
When you design and code with accessibility in mind from the start, it doesn’t add extra work — it reduces it.
Accessible code tends to be cleaner, more semantic, and easier to maintain.
Semantic HTML, clear APIs, and predictable structures help everyone — users, developers, and assistive tech alike.
Accessibility isn't a bonus. It's a mark of quality engineering.
A Personal Note: Progress, Not Perfection
Even this website isn’t perfect — and that’s okay. Accessibility is a journey, not a checkbox.
This site meets WCAG 2.1 AA standards, maintains solid color contrast, includes ARIA labels, and follows a logical document structure. But there’s always room for improvement.
The goal isn’t perfection. It’s progress.
Every commit that improves accessibility — even a single ARIA label — brings us closer to building software that truly works for everyone.