Skip to main content
Back to Blog

Web Accessibility: The Main Principles for Developers

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