Back to Blog

Web Accessibility: The Main Principles for Developers

April 27, 2025

Accessibility (often abbreviated as a11y) ensures that websites are usable by everyone, including people with disabilities (visual, motor, cognitive, auditory). Accessibility is not just a legal requirement in many countries — it's also about inclusive design and better UX for all.


1. Why Accessibility Matters

  • 1.3 billion people worldwide live with a disability.
  • Accessibility improves SEO, usability, and user satisfaction.
  • It is mandated by laws like the ADA (US), RGAA (France), and EN 301 549.

Example: Imagine a blind user relying on a screen reader to do their grocery shopping online. Without accessible design, this simple task becomes frustrating or impossible.


2. WCAG Guidelines

WCAG (Web Content Accessibility Guidelines) defines 4 core principles:

POUR: Perceivable, Operable, Understandable, Robust

Each principle includes testable success criteria organized into 3 levels:

  • A (minimum)
  • AA (recommended)
  • AAA (advanced)

📚 WCAG 2.2 Guidelines


3. Semantic HTML

Using correct HTML tags improves accessibility out of the box.

✅ Examples:

  • Use <button> instead of clickable <div>
  • Headings (<h1> to <h6>) should follow a logical hierarchy
  • Use <label for="id"> linked to <input id="id">
  • Use <nav>, <main>, <footer> for structure

📚 W3Schools - HTML Semantic Elements
📚 MDN Web Docs - Semantics


4. Keyboard Navigation

Ensure your site works without a mouse.

  • Use tabindex="0" to make elements focusable
  • Avoid tabindex > 0 (use natural flow)
  • Focus indicators should be visible (avoid outline: none)
  • Test all components using Tab, Enter, Space, Esc, and Arrow keys


5. ARIA Roles & Attributes

ARIA (Accessible Rich Internet Applications) provides extra semantics when HTML lacks them.

Useful roles:

<div role="alert">Form error</div>
<nav role="navigation" aria-label="Main menu">...</nav>

Essential ARIA attributes with concrete examples:

  • aria-label — provides an accessible name:
<button aria-label="Close menu">×</button>

  • aria-labelledby — references visible text as label:
<h2 id="sectionTitle">User Settings</h2>
<div role="region" aria-labelledby="sectionTitle">
  <!-- content -->
</div>

  • aria-describedby — provides additional description:
<input id="email" aria-describedby="emailHelp" />
<span id="emailHelp">We'll never share your email.</span>

🚫 Avoid ARIA when native elements do the job.

📚 WAI-ARIA Authoring Practices


6. Color and Contrast

Text should have enough contrast with the background.

  • Use tools like Contrast Ratio

  • Aim for at least 4.5:1 for normal text (Level AA)

  • Never rely on color alone to convey meaning

✅ Add icons, patterns, or labels to color-coded UI

Besides Contrast Ratio, try the Color Contrast Analyzer tool — widely used by accessibility auditors.


7. Screen Readers

Screen readers read content for blind/low-vision users.

To support them:

  • Use alt on images

  • Hide decorative elements with aria-hidden="true"

  • Use aria-live="polite" or "assertive" for dynamic updates

  • Use landmarks (<main>, <nav>, <aside>)


8. Images and Media

For images:

  • Use meaningful alt text:
<img src="chart.png" alt="Bar chart showing sales in Q1" />

  • Use empty alt="" for decorative images.

For videos:

  • Provide captions or a transcript

  • Use semantic <video> and <audio> tags


9. Forms

  • Use associated <label>

  • For multi-step or grouped fields, use <fieldset> to group related controls and <legend> to provide a descriptive label.

<fieldset>
  <legend>Shipping Address</legend>
  <!-- form fields here -->
</fieldset>
  • Provide helpful aria-describedby messages

  • Show errors with clear, visible, and screen reader-friendly messages


10. Error Handling

  • Errors must be clear and accessible

  • Announce errors using role="alert"

  • Provide suggestions when possible

  • Ensure focus returns to the error section


11. Accessible Components

Custom components (dropdowns, modals, tabs) must be:

  • Focusable

  • Navigable by keyboard

  • Described with ARIA roles if necessary

📚 Inclusive Components


12. Mobile Accessibility

Accessibility applies to mobile too:

  • Use responsive design and avoid small tap targets

  • Don't rely on hover

  • Test with screen readers (VoiceOver, TalkBack)


13. Testing Tools

✅ Manual testing:

  • Navigate with keyboard only

  • Use screen reader (NVDA, JAWS, VoiceOver)

✅ Automated tools:


14. Testing Strategy

Accessibility testing should be:

  1. Early (during development)

  2. Often (CI/CD)

  3. Manual + Automated

Include accessibility checks in PRs and QA cycles.

Reminder: Automated tools catch only about 30–50% of accessibility issues and should never replace manual testing.


Some legal frameworks:

  • 🇺🇸 ADA, Section 508

  • 🇫🇷 RGAA, Loi pour une République numérique

  • 🇪🇺 EN 301 549 (Digital Accessibility Act)

Non-compliance can lead to lawsuits, fines, and exclusion.


16. Accessibility in CI/CD

Integrate a11y into pipelines:

# Example with axe CLI
npx axe https://example.com --save results.json

Or use pa11y-ci for continuous testing.


17. Accessibility in Single Page Applications (SPAs)

SPAs can introduce accessibility challenges due to dynamic content updates and JavaScript-driven navigation.

  • Ensure the focus moves to meaningful content after route changes (mainRef.current.focus()).

  • Use aria-live to announce page updates or route transitions.

  • Maintain landmarks (<main>, <nav>, etc.) across views for screen reader consistency.

React Router example for focus management:

import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  const mainRef = useRef<HTMLElement>(null);
  const location = useLocation();

  useEffect(() => {
    mainRef.current?.focus();
  }, [location.pathname]);

  return (
    <main tabIndex={-1} ref={mainRef}>
      {/* app content */}
    </main>
  );
}


18. Internationalization and Accessibility (i18n + a11y)

Supporting multiple languages requires attention to screen reader behavior.

  • Set the correct lang attribute on <html> or specific elements.

  • Avoid mixing languages without appropriate markup (e.g., lang="en" inside lang="fr").

  • Update ARIA labels and descriptions dynamically when switching languages.


19. Advanced Focus Management

Managing focus is critical in complex components like modals, tabs, or dropdowns.

  • Trap focus within modals using libraries like focus-trap.

  • Return focus to the triggering element when the modal is closed.

  • Use aria-modal="true" and label modals with aria-labelledby.


20. Animations and Accessibility

Animations can cause motion sickness or distract users.

  • Respect the user's system preferences with:

@media (prefers-reduced-motion: reduce) {
  animation: none;
}
  • Avoid unnecessary motion or provide an option to disable it.

  • Ensure animations do not interfere with screen reader timing.

When content updates slowly (e.g., loaders or transitions), use aria-busy="true" to inform assistive technologies that the region is updating.

<div aria-busy="true">Loading content...</div>


21. Cognitive Accessibility

Make interfaces easier for users with cognitive disabilities.

  • Reduce cognitive load with simple layouts and clear instructions.

  • Combine icons with descriptive text.

  • Avoid time-limited tasks without options to extend or disable timers.

  • Allow interface personalization (text size, contrast, spacing).


22. Accessible Data Tables

Tables with lots of data require semantic markup for screen readers.

  • Use <th> with scope="col" or scope="row" to define headers.

  • For complex tables, associate headers with headers attribute.

  • Add <caption> and summary for screen reader context.

  • Avoid layout tables — use CSS grid or flexbox instead.


23. E-commerce Accessibility

Online stores must ensure that all users can browse and complete purchases.

  • Clearly indicate item states (e.g., "Out of Stock", "On Sale").

  • Announce updates like cart additions with aria-live regions.

  • Make filters, sliders, and product sorters keyboard-accessible.


24. Tooltips, Popovers, and Accessible Hints

Small UI elements can often be problematic.

  • Do not rely solely on hover; tooltips must be accessible by keyboard.

  • Trigger tooltips with focusable elements.

  • Use aria-describedby to link hints to form fields or buttons.


25. Inclusive UX Design Practices

Accessibility begins with thoughtful UX.

  • Offer multiple ways to interact: click, keyboard, voice commands.

  • Use accessible design tokens (contrast ratios, spacing, font choices).

  • Involve users with disabilities in usability testing and feedback cycles.

  • Provide consistent navigation and error prevention across pages.


26. Common Pitfalls

  • Non-descriptive link texts (e.g., "Click here")

  • Inaccessible modals and dropdowns

  • Content updates without notifying assistive tech

  • Dynamic content without keyboard support


27. Tips for Developers

  • Use semantic HTML before ARIA

  • Think about keyboard users at every step

  • Use linters like eslint-plugin-jsx-a11y

  • Pair with designers to choose accessible colors and components


Developer A11Y Checklist

  • Semantic HTML is used (headings, tags, form elements, etc.).

  • The site is fully usable with keyboard only.

  • Color contrast meets at least WCAG AA (4.5:1 for normal text).

  • Dynamic components (modals, dropdowns, etc.) are accessible.

  • All images have meaningful alt attributes.

  • Errors are clearly visible and announced to screen readers.

  • Accessibility has been tested manually:

    • Using keyboard only.

    • With axe DevTools.

    • With a screen reader (e.g., NVDA, VoiceOver).

  • Accessibility checks are part of the CI/CD pipeline.


Conclusion

Accessibility is not only a checkbox — it's a mindset.

“When we design for disability, we all benefit.” — Inclusive Design Principles


Further Reading & Official Resources