Building an Accessible Design System: A Practical Guide

Building an Accessible Design System: A Practical Guide
Why accessibility can't be retrofitted and how to build it in from day one
An accessible design system is one where the accessible choice is the default choice, not an optional variant that designers and developers have to remember to add. This article covers the principles, core components (buttons, forms, modals, navigation), testing practices, documentation, and governance needed to build accessibility in from day one, based on lessons learned the hard way.
I'll never forget the moment our design system broke for a screen reader user.
We'd spent months building it. Hundreds of components. Meticulous documentation. Pixel-perfect consistency across every product. Everyone was proud. Then we watched someone who's blind try to use a component we'd marked as "accessible": proper contrast, semantic HTML, all the checkboxes ticked.
She couldn't figure out what the button did. The label we thought was "clear" made no sense without visual context. Our carefully designed states were invisible to her screen reader. Our "accessible" component wasn't accessible at all.
That's when I learned the hard truth: you can't bolt accessibility onto a design system after the fact. It's not a layer you add. It's the foundation you build on.
This article shares what I've learned about building accessible design systems, not from theory, but from the humbling experience of getting it wrong, learning from real users, and slowly figuring out how to get it right.
What makes a design system truly accessible?
An accessible design system isn't just a collection of WCAG-compliant components. It's a system that makes it easier to build accessible products than inaccessible ones.
Think about that for a moment. Your design system should make the right choice the default choice. It should be harder to create an inaccessible button than an accessible one. The path of least resistance should lead to inclusion.
This means it's not enough to offer an accessible variant. The default should be accessible. Designers shouldn't need to remember to add focus states; they should be built in. Developers shouldn't need to hunt for ARIA patterns; they should be included in every component.
When accessibility is optional, it gets skipped. When it's the default, it gets used.
Starting with the hard questions
Before you build a single component, you need to answer some uncomfortable questions:
Who's been excluded from using our products? Not theoretically, actually. Talk to users who've struggled. Find out where your current system fails. This is painful but essential.
What assumptions are we making about our users? We all make them. Everyone has perfect vision. Everyone uses a mouse. Everyone understands our clever microcopy. List your assumptions. Then challenge every single one.
How will we know if our components actually work? Not just pass automated tests, actually work for real people using assistive technologies. What's your testing process? Who's involved?
I spent years avoiding these questions. It's easier to focus on the technical stuff: color tokens, spacing scales, component APIs. But if you don't start with the hard questions, you'll build an accessible-looking system that excludes people.
Core principles for accessible components
1. Make focus states obvious and beautiful
Focus indicators are not optional decorations. They're way finding for keyboard users. If someone can't see where they are, they can't use your product.
Yet somehow, we've normalized invisible or barely-visible focus states. Or worse, we remove them entirely because we think they "look ugly."
Here's the truth: if your focus states are ugly, fix the design. Don't remove the focus states.
What actually works:
- Minimum 3:1 contrast ratio against adjacent colors, and a minimum outline thickness of 2 CSS pixels, as required by WCAG 2.2's Focus Appearance criterion (2.4.11)
- Visible offset from the component (not directly on the edge where it disappears)
- Works in both light and dark modes
- Consistent pattern across all interactive elements
And here's what I've learned: well-designed focus states aren't ugly. They can be beautiful. They can be part of your brand. Some of the most elegant interfaces I've seen have gorgeous focus states that enhance the design.
2. Build interactive states into every component
Every interactive component has states: default, hover, focus, active, disabled, loading, error. For accessible components, you need to design and code all of them. Not just visually, but for screen readers too.
For each state, ask:
- What does this look like?
- What does this sound like to a screen reader?
- How does this feel to use with a keyboard?
- What happens on a touch device?
I've seen so many components that work beautifully with a mouse but fall apart with keyboard navigation. Or look perfect but announce gibberish to screen readers. That's because someone designed the happy path and forgot the rest.
3. Write component documentation for everyone
Good documentation isn't just code examples and props tables. It should answer:
For designers:
- When to use this component (and when not to)
- Required color contrast ratios
- Minimum touch target sizes
- Focus and keyboard behavior
- How to write accessible labels
For developers:
- Semantic HTML structure
- Required ARIA attributes
- Keyboard interaction patterns
- Screen reader announcements
- Common implementation mistakes and how to avoid them
For content writers:
- How to write clear, helpful labels
- Patterns for error messages
- Microcopy guidance
- Alt text examples
Everyone needs to understand accessibility, not just the "accessibility person."
Essential accessible components
Buttons: the foundation
If you can't get buttons right, nothing else matters. Buttons are everywhere. They're how people do things.
Accessible buttons need:
- Clear, descriptive labels that work out of context (not "Click here" or "Submit")
- Minimum touch target of 44x44 points, per Apple's Human Interface Guidelines, or 48x48dp, per Google's Material Design guidelines
- Visible focus indicator
- Disabled state that's programmatically announced
- Loading state that tells screen readers what's happening
Real example that taught me a lesson:
We had a "Save" button that turned into a spinner during loading. Visually clear. But screen readers had no idea anything was happening. Users kept clicking repeatedly because they couldn't tell if it worked.
The fix? An aria-live="polite" region announcing "Saving..." and then "Saved!" Simple. But we didn't think about it until someone pointed out the problem.
Forms: where accessibility often breaks
Forms are accessibility minefields. They're also where most people abandon your product.
Every form component needs:
- Clear labels associated with inputs (
<label for="">, not just placeholder text) - Helpful error messages that appear near the field with the problem, explain what's wrong, and suggest how to fix it
- Input types that trigger the right mobile keyboards (
type="email",type="tel",type="number") - Grouped fields using
<fieldset>and<legend>for related inputs like addresses or payment info - Clear validation that works for everyone, not just color-coded borders
Real example:
Our registration form used red borders for errors. Only red borders. Someone with color blindness had no idea which fields had problems. They kept submitting, getting rejected, growing frustrated.
We added error icons and text messages near each field. Problem solved for everyone: color blind users, screen reader users, and everyone else who benefits from clear communication.
Modals: navigation nightmares or accessible dialogs?
Modals can trap keyboard users if you're not careful. I've been stuck in modal hell myself, tabbing in circles, unable to escape, ready to close the browser out of frustration.
Accessible modals require:
- Focus trap (tab cycles through modal content, doesn't escape to background)
- Escape key closes the modal
- Focus returns to trigger element when closed
aria-modal="true"androle="dialog"aria-labelledbypointing to modal title- Background content marked
aria-hidden="true"
Sounds complicated. It is. That's why your design system should handle it automatically. Designers and developers shouldn't need to remember all this; the component should do it for them.
Navigation: making it work for everyone
Navigation seems simple until you try to use it with a keyboard. Or a screen reader. Or while zoomed in 200%.
Accessible navigation needs:
- Skip links ("Skip to main content") for keyboard users
- Current page indicator visible to everyone, announced to screen readers
- Mega menus that don't trap focus
- Mobile menu that works with screen readers
- Consistent, logical tab order
Lesson learned the hard way:
Our mega menu worked perfectly with a mouse. With a keyboard? Nightmare. It would close before you could tab to the second column. Keyboard users literally couldn't access half our site.
The fix required rethinking the interaction pattern entirely. Sometimes accessibility means changing how something fundamentally works, not just adding ARIA.
Color and typography systems for accessibility
Building a contrast-safe color palette
You can't just pick colors you like and hope they pass contrast checks. You need a system
Start with contrast ratios as constraints, per WCAG 2.2's contrast success criteria:
- 4.5:1 for normal text on backgrounds (Level AA)
- 3:1 for large text (18pt+) and UI components (Level AA)
- 7:1 for enhanced accessibility (Level AAA)
Then build your palette around these ratios. Test every text color against every background color you'll use. Document which combinations work.
This sounds tedious. It is. Do it anyway. Otherwise, designers will innocently choose inaccessible combinations, and you'll have to fix them later, which means either breaking consistency or shipping inaccessible products.
Pro tip: Build a contrast checker into your design tool. Make it impossible to use inaccessible combinations.
Typography that scales
Fixed font sizes break for users who need larger text. But just making text bigger isn't enough; your layouts need to handle it gracefully.
Essential practices, aligned with WCAG's guidance on visual presentation and resizing:
- Use relative units (rem, em), not pixels
- Test at 200% zoom minimum
- Design components that work at multiple scales
- Maintain comfortable line length (roughly 50–75 characters; WCAG's own recommendation caps it at 80)
- Keep line height at 1.5 minimum for body text
I've seen beautiful designs that completely break when someone increases text size. Text overlaps, buttons disappear, layouts become unusable. Your design system should prevent this by default.
Testing your design system with real assistivetechnologies
Automated tools are a useful first pass, but research from Deque Systems puts their typical coverage at only around 20–30% of WCAG failures. The rest needs humans.
Test every component with:
Screen readers:
- VoiceOver (iOS/macOS), most commonly used
- NVDA (Windows), free and widely used
- JAWS (Windows), common in enterprises
- TalkBack (Android)
Keyboard navigation:
- Tab through everything
- Try to use every feature without a mouse
- Check if focus indicators are visible
- Verify tab order makes sense
Screen magnification:
- Zoom to 200% minimum
- Check if everything still works
- Verify nothing's cut off or overlapping
Voice control:
- Try using components entirely by voice
- Check if visible labels match voice command names
Real users: Pay people with disabilities to test your system. Their feedback is worth more than any automated tool.
Documentation that actually helps
I've seen so many design systems with technically perfect components and useless documentation.
Your documentation should answer:
- "Should I use this component?" Clear use cases and when to choose alternatives
- "How do I make this accessible?" Step-by-step guidance with examples
- "What does 'accessible' actually mean here?" Explain the why, not just the how
- "What if I need to customize it?" Guidelines for maintaining accessibility when adapting
- "How do I test if I did it right?" Testing checklists and common issues
Include real examples. Show both good and bad implementations. Explain what makes them good or bad. Make it educational, not just prescriptive.
Governance: keeping accessibility alive
A design system without governance becomes inconsistent chaos. For accessibility, the stakes are higher: inconsistent accessibility means some people can't use your products.
You need:
- Clear ownership: Who's responsible for accessibility? (Hint: everyone, but someone needs to coordinate)
- Review process: How do new components get approved? What's the accessibility checklist?
- Testing requirements: What must be tested before a component ships?
- Update process: How do you fix accessibility issues in existing components?
- Communication: How do you tell teams when something changes?
The hardest part isn't building an accessible design system. It's maintaining it as it grows and evolves.
Real-world example: learning from failure
Let me share a story about when we got it spectacularly wrong.
We built a data table component. Beautiful. Responsive. Sortable. Filterable. Complex but powerful. We were proud.
Then we watched someone using a screen reader try to use it. They couldn't tell which column they were in. Couldn't understand the sort state. Got completely lost in nested table structures. Couldn't filter anything because the controls made no sense without visual context.
We'd built a component that only worked if you could see it.
What we learned:
- Test early, test often. Don't wait until it's "done."
- Complex components need extra accessibility attention. The more complex, the more can go wrong.
- Visual affordances aren't enough. Everything needs to work non-visually too.
- Sometimes you need to simplify. Some features that work great visually don't translate to screen readers. That's okay. Build a simpler version that works for everyone.
We rebuilt the table from scratch. Simpler. More semantic. Clear announcements for every state change. It was less visually fancy but far more usable.
Better for screen reader users. Easier for keyboard navigation. Simpler for developers to implement. And honestly? Still beautiful.
Final thoughts: accessibility as craft
Building an accessible design system isn't a checklist you complete. It's a craft you practice.
You'll get things wrong. I still get things wrong. Every design system has accessibility gaps. The question is: what do you do when you find them?
Do you fix them? Do you document them? Do you learn from them? Or do you mark the ticket as "nice to have" and move on?
The difference between accessible and inaccessible design systems isn't perfection. It's commitment. It's caring enough to keep trying, keep learning, keep improving.
Start small. Pick one component. Make it truly accessible, tested with real assistive technologies, documented thoroughly, easy to use correctly. Then do another. And another.
Over time, you'll build a system that doesn't just claim to be accessible. It actually is.
Your users, all of them, will thank you. And you might just discover that designing for everyone makes you a better designer.
Quick Start Checklist
Ready to start building accessible components? Start here.
For your first accessible component:
- Design focus states for all interactive elements
- Test with keyboard navigation (no mouse!)
- Test with a screen reader (VoiceOver or NVDA)
- Document when to use it and why
- Include code examples with ARIA
- Test at 200% zoom
- Get feedback from someone who uses assistive tech
For your design system:
- Define color contrast rules (minimum 4.5:1)
- Set minimum touch target sizes (44x44px minimum)
- Create focus indicator patterns
- Document keyboard interactions
- Build testing into your review process
- Plan for regular accessibility audits
Start with these. Build onthem. Keep learning.
FAQ
What does it mean for a design system to be "accessible"?
It means accessible components are the default, not an optional variant, so it's harder to build something inaccessible than something accessible.
Can I just retrofit accessibility onto an existing design system?
It's possible, but much harder than building it in from the start. Retrofitting usually means auditing every component individually, whereas building it in means new components inherit accessibility automatically.
How much of accessibility testing can be automated?
Research from Deque Systems suggests automated tools catch roughly 20–30% ofWCAG failures. The rest, things like whether a label actually makes sense, or whether a sort order is announced correctly, requires manual testing with real assistive-technology users.
What's the minimum touch target size for buttons?
44x44 points on iOS (Apple's Human Interface Guidelines) and 48x48dp on Android (Google's Material Design guidelines).
Who should own accessibility in a design system?
Everyone contributes, but a design system typically needs a designated owner or working group to coordinate reviews, testing requirements, and updates.
Building an accessible design system at your company? At Hyphen, we help teams embed accessibility from the ground up, not as an afterthought, but as a foundation. Let's talk about how we can help you build a system that works for everyone.





.jpeg)

