AppMaker Studio
Web

Web Accessibility: A Practical Guide for Developers

Andy
January 27, 2026
9 min read

Web accessibility is no longer a bonus: it's a legal requirement in many countries and above all an ethical issue. Yet too many developers still consider a11y as a constraint. Here's how to integrate it naturally into your workflow.

Why Accessibility Matters

15% of the world's population lives with a disability. Ignoring accessibility means excluding millions of potential users from your applications.

Good accessibility practices improve the experience for everyone: keyboard navigation, readable contrasts, and semantic structure benefit every user.

SEO and accessibility are linked. Google values well structured sites with alternative content for images and clear heading hierarchy.

WCAG 2.2 Basics

WCAG (Web Content Accessibility Guidelines) defines 4 principles: Perceivable, Operable, Understandable, Robust. Each criterion has 3 levels: A, AA, AAA.

Aim for AA level minimum. This includes: 4.5:1 contrast ratios for text, complete keyboard navigation, alt text for images, and labels for forms.

WCAG 2.2 (2023) adds important criteria: minimum touch target size (24x24 CSS pixels), accessible authentication, and consistent contextual help.

Semantic HTML: Your First Tool

Use the right HTML elements. A <button> is keyboard clickable and correctly announced by screen readers. A <div onClick> is not.

Structure with <header>, <main>, <nav>, <article>, <aside>, <footer>. These landmarks allow assistive technology users to navigate quickly.

Respect heading hierarchy. One <h1> per page, then <h2>, <h3>... without skipping levels. It's your content outline.

html
<!-- ❌ Bad: inaccessible div soup -->
<div class="header">
  <div class="nav">...</div>
</div>
<div class="content">
  <div class="title">My title</div>
</div>

<!-- ✅ Good: semantic HTML -->
<header>
  <nav aria-label="Main navigation">...</nav>
</header>
<main>
  <h1>My title</h1>
</main>

ARIA: When and How to Use It

ARIA (Accessible Rich Internet Applications) complements HTML when native elements aren't enough. Golden rule: only use ARIA if necessary.

Common roles: role='button' for a non button interactive element, role='alert' for urgent messages, role='dialog' for modals.

aria label and aria labelledby name elements. aria describedby adds a description. aria live announces dynamic changes.

tsx
// Accessible component with ARIA
function SearchInput() {
  const [results, setResults] = useState([]);
  
  return (
    <div>
      <label htmlFor="search">Search</label>
      <input 
        id="search"
        type="search"
        aria-describedby="search-hint"
        aria-controls="search-results"
      />
      <p id="search-hint" className="sr-only">
        Type at least 3 characters
      </p>
      <ul 
        id="search-results"
        role="listbox"
        aria-live="polite"
      >
        {results.map(r => (
          <li key={r.id} role="option">{r.title}</li>
        ))}
      </ul>
    </div>
  );
}

Testing and Tools

Integrate accessibility tests into your CI. axe core with jest axe or Playwright automatically detects common violations.

Test manually with keyboard: Tab to navigate, Enter/Space to activate, Escape to close. If you're stuck, your users will be too.

Use a screen reader. VoiceOver (Mac), NVDA (Windows free) or TalkBack (Android). 30 minutes of testing reveals issues that automated tools miss.

Conclusion

Accessibility isn't a feature you add at the end. It's a development approach that benefits everyone. Start with semantic HTML, test with keyboard, and improve progressively. Every improvement counts.

Related articles