Skip to main content

Accessibility in Web Development: Building Inclusive Interfaces

Created: March 9, 2026 CalmOps 3 min read

Introduction

Web accessibility ensures people with disabilities can use websites effectively. Beyond compliance, accessible design improves usability for everyone. This guide covers building inclusive web experiences.

Why Accessibility Matters

Statistics

  • 15% of world population has some disability
  • 1 billion people affected
  • Growing as population ages

Benefits

  • Legal compliance
  • SEO improvement
  • Broader audience
  • Better usability
  • Ethical responsibility

WCAG Guidelines

Four Principles (POUR)

  • Perceivable: Can be perceived by users
  • Operable: Interface components work
  • Understandable: Information is understandable
  • Robust: Content works with current and future tools

Levels

Level Description
A Basic accessibility
AA Addresses most common barriers
AAA Highest level, not always achievable

Semantic HTML

Use Proper Elements

<!-- Bad -->
<div onclick="submit()">Submit</div>

<!-- Good -->
<button type="submit">Submit</button>

Headings

<h1>Main Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>

<!-- Skip levels: h1 -> h3 is bad -->
<!-- Link: Navigate somewhere -->
<a href="/about">About Us</a>

<!-- Button: Perform action -->
<button>Save</button>
<button>Open menu</button>

Keyboard Navigation

Focus Indicators

/* Always visible focus */
:focus {
  outline: 3px solid #2563EB;
  outline-offset: 2px;
}

/* Only show when using keyboard */
:focus:not(:focus-visible) {
  outline: none;
}

Tab Order

<!-- Logical tab order -->
<form>
  <label for="name">Name</label>
  <input id="name" type="text" tabindex="1">
  
  <label for="email">Email</label>
  <input id="email" type="email" tabindex="2">
</form>
<a href="#main" class="skip-link">Skip to main content</a>

<style>
.skip-link {
  position: absolute;
  left: -999px;
}
.skip-link:focus {
  left: 0;
}
</style>

ARIA

When to Use ARIA

  • Enhancing native HTML
  • Custom widgets
  • Live regions

ARIA Rules

  1. Use native HTML when possible
  2. Never change native semantics
  3. All interactive ARIA needs keyboard support

ARIA Attributes

<!-- Landmark roles -->
<header role="banner">
<main role="main">
<nav role="navigation">
<footer role="contentinfo">

<!-- Interactive widget -->
<button aria-label="Close menu" aria-expanded="false">
<div role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50">

Live Regions

<!-- Announce updates -->
<div aria-live="polite">Changes saved</div>
<div aria-live="assertive">Error: Invalid input</div>

Images and Media

Alt Text

<!-- Descriptive -->
<img src="cat.jpg" alt="Orange tabby cat sitting on windowsill">

<!-- Empty for decorative -->
<img src="decoration.png" alt="">

<!-- Complex image -->
<img src="chart.png" alt="Bar chart showing sales growth">

Captions and Transcripts

  • Video: Captions
  • Audio: Transcripts
  • Charts: Text alternatives

Forms

Labels

<!-- Explicit label -->
<label for="email">Email</label>
<input id="email" type="email">

<!-- Implicit label -->
<label>
  Email
  <input type="email">
</label>

Error Handling

<input 
  id="phone" 
  type="tel"
  aria-invalid="true"
  aria-describedby="phone-error"
>
<span id="phone-error" role="alert">
  Please enter a valid phone number
</span>

Required Fields

<label for="name">
  Name (required)
  <input id="name" required aria-required="true">
</label>

Color and Contrast

WCAG Contrast Ratios

  • Normal text: 4.5:1 (AA)
  • Large text: 3:1 (AA)
  • UI components: 3:1 (AA)

Tools

Don’t Rely on Color

<!-- Bad: Color only -->
<span class="error">Invalid</span>

<!-- Good: Icon + color + text -->
<span class="error">
  <svg aria-hidden="true">...</svg>
  Invalid input
</span>

Testing

Automated Testing

  • axe DevTools
  • WAVE
  • Lighthouse

Manual Testing

  • Keyboard navigation
  • Screen reader testing
  • Zoom to 200%
  • Disable CSS/images

Screen Readers

  • NVDA (Windows)
  • VoiceOver (Mac)
  • JAWS (Windows)
  • TalkBack (Android)

Browser Tools

  • Accessibility Inspector (Firefox)
  • Accessibility pane (Chrome)

Responsive Design

Text Scaling

/* Use relative units */
body {
  font-size: 100%;  /* or 1rem */
  line-height: 1.5;
}

Touch Targets

/* Minimum 44x44 pixels */
button, a {
  min-height: 44px;
  min-width: 44px;
}

Conclusion

Accessibility is essential, not optional. Start with semantic HTML, ensure keyboard navigation, use ARIA correctly, and test with real tools. Accessible websites work better for everyone.


Resources

Comments

Share this article

Scan to read on mobile