Accessibility (A11y) means designing and developing software that is usable by everyone, including people with disabilities. It is not optional β it is essential. Accessibility improves usability, search engine optimization, legal compliance, and above all, equality.
This guide provides concrete best practices for developers, designers, and teams to build accessible software, based on the WCAG (Web Content Accessibility Guidelines) 2.2 standard, inclusive UX principles, and modern tooling.
π Accessibility Principlesβ
Use the POUR framework from WCAG:
Principle | Description |
---|
Perceivable | Users must be able to perceive the information (e.g., alt text, color contrast, captions) |
Operable | Users must be able to operate the interface at their own pace, without being limited by time constraints (e.g., no automatic timeouts, disappearing content, or time-limited form submissions). |
Understandable | Content must be clear and predictable (e.g., consistent navigation, error messages) |
Robust | Must work with a wide range of assistive technologies (e.g., screen readers, ARIA support) |
β
If your app follows POUR, itβs already around 90% accessible.
π Key Rules from WCAGβ
The WCAG 2.2 defines accessibility rules under the four POUR core principles. Below are the most essential rules every team should apply:
Perceivableβ
Rule | Description |
---|
Provide text alternatives | Every image must have meaningful alt text or alt="" if decorative |
Ensure sufficient contrast | Text must have a minimum contrast ratio of 4.5:1 (normal) or 3:1 (large text) |
Donβt rely on color alone | Use icons, labels, or patterns in addition to color (e.g., for status indicators) |
Provide captions and transcripts | Videos must have captions, audio must have transcripts |
Responsive layout | Content must be readable and reflow on different screen sizes and zoom levels |
Operableβ
Rule | Description |
---|
Everything must be keyboard accessible | All interactive elements must be usable via Tab , Enter , Space |
Provide visible focus states | Show a clear visual indicator when an element is focused |
Avoid keyboard traps | Users must always be able to move in and out of modals or widgets using the keyboard |
Use logical tab order | Elements must follow a logical, intuitive tabbing sequence |
Avoid flashing content | No more than 3 flashes per second (prevents seizures) |
Understandableβ
Rule | Description |
---|
Use clear, consistent language | Avoid jargon, write labels and error messages clearly |
Label all inputs properly | Use <label> elements and associate them with their form controls |
Explain errors and how to fix them | Donβt just show βInvalidβ β explain what went wrong and how to correct it |
Provide consistent navigation | Menus and layout should not change unexpectedly between pages |
Use heading hierarchy | Do not skip heading levels (<h1> β <h2> β <h3> ) |
Warn before timeouts or destructive actions | Inform users when an action is permanent or a session will expire |
Rule | Description |
---|
Use semantic HTML | Use proper elements (<button> , <nav> , <main> ) for better screen reader support |
Use ARIA only when necessary | Prefer native HTML before using ARIA roles |
Ensure compatibility with assistive tech | Test with screen readers (e.g., NVDA, VoiceOver) and alternative input methods |
Validate your HTML | Broken markup can prevent assistive tools from interpreting your page |
Minimum WCAG Levelsβ
Level | Meaning |
---|
A (Minimum) | Basic accessibility β not enough for modern standards |
AA (Recommended) β
| Industry standard β sufficient for most legal and usability requirements |
AAA (Advanced) | Highest level β ideal, but not always practical for all content types |
β
Aim for WCAG 2.2 Level AA as the minimum standard in every web project.
Tool | Integration | Purpose |
---|
axe-core | Browser extension, GitHub Action, CLI, CI pipelines, Figma | Industry-standard automated A11y testing |
WAVE | Browser extension | Web Evaluation Tool |
eslint-plugin-jsx-a11y | ESLint | Lints JSX for accessibility issues |
storybook-addon-a11y | Storybook | Instant feedback on component accessibility |
cypress-axe | Cypress | E2E tests with accessibility assertions |
jest-axe | Jest | Unit tests for accessibility violations |
Pa11y | CLI, CI | Site-wide accessibility reports |
Tool | Purpose |
---|
axe-core | Industry-standard automated A11y testing |
Stark | Color contrast checker, vision simulation |
Able | Color vision simulator |
Contrast | Quick WCAG AA/AAA check in Figma |
βοΈ DevOps / CI Integrationβ
- Integrate axe-core or Pa11y into GitHub Actions, GitLab CI, or Jenkins to catch issues automatically in PRs.
- Sample GitHub Action with
axe
:
- uses: dequelabs/axe-linter-action@v1
with:
api_key: ${{ secrets.AXE_LINTER_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
β
Quick Checklist for Developersβ
- Use real
<button>
elements with clear, visible text or accessible aria-label
.
- Use real
<a href="">
for all links that navigate β not <div>
or <span>
.
- All interactive components (menus, modals, sliders) are fully keyboard accessible.
- All buttons, inputs, links show a visible focus ring (never remove it!).
- Use a clear heading structure: one
<h1>
, then logical levels (<h2>
, <h3>
, β¦).
- All images have meaningful
alt
attributes, or alt=""
if decorative.
- Every form input has a visible
<label>
, and all fields are grouped logically.
- Errors are explained in text, not just with color or icons.
- Text and UI elements meet WCAG AA contrast (4.5:1 for body text, 3:1 for large).
- Use semantic HTML elements (
<nav>
, <main>
, <section>
, <ul>
, etc.).
- Do not rely on color alone β always include text, icons, or shapes.
- Animations should be subtle and non-distracting. If motion is used, ensure that users who prefer reduced motion can opt out through system settings.
- All modals/dialogs are focus-trapped and closable with
Esc
.
- No keyboard traps β users must always be able to navigate forward and back.
- Use ARIA roles and attributes only when needed, and never to βfixβ bad HTML.
- Ensure responsive layout: zoomable, screen-reader friendly, mobile accessible.
- Run automated tests with tools like axe-core, eslint-plugin-jsx-a11y, or Pa11y.
- Test with a screen reader at least once (VoiceOver, NVDA, or TalkBack).
π Learn Moreβ
π Final Thoughtsβ
Accessibility is not a feature, itβs a baseline. Make it part of your design, code, review, and testing process β from day one.
βAccessibility is not about disability, itβs about universal usability.β