Skip to main content

Accessibility

Build inclusive software that works for users with disabilities and diverse abilities.

TL;DR

Accessibility means building software that works for everyone, including people with disabilities. Follow WCAG 2.1 AA standards: semantic HTML, keyboard navigation, sufficient color contrast, text alternatives for images, proper headings, labels for form fields. Accessibility isn't a feature layer added at the end—it's built in from the start. Use alt text for images, proper button and link semantics, ARIA labels when needed. Support keyboard-only navigation. Test with screen readers and actual users with disabilities. Accessibility benefits everyone: captions help in noisy environments, keyboard navigation helps power users, clear labeling reduces confusion. It's both ethical and practical.

Learning Objectives

  • Understand WCAG 2.1 AA standards and compliance levels
  • Implement semantic HTML correctly
  • Ensure keyboard navigation and focus management
  • Design with sufficient color contrast and readable fonts
  • Provide text alternatives for non-text content
  • Use ARIA attributes appropriately
  • Test with actual assistive technology and disabled users
  • Understand how accessibility benefits all users

Motivating Scenario

A company launches an e-commerce site without considering accessibility. Blind users can't navigate because the site relies on color alone to indicate status. Users with mobility issues can't use the keyboard to interact. Form fields lack labels, confusing screen reader users. A user with low vision struggles with low-contrast text. When the company faces a lawsuit and discovers they've excluded millions of potential customers, they begin accessibility retrofitting—expensive and difficult. Building accessibility in from day one would have cost less and served more users.

Core Concepts

WCAG 2.1 Levels

WCAG 2.1 AA is the standard for web accessibility. A = accessible to most; AA = accessible to more; AAA = accessible to as many as possible. Most organizations target AA.

Semantic HTML

HTML elements carry meaning beyond visual presentation. Use <button> for buttons, <a> for links, <nav> for navigation, <label> for form labels. Screen readers and assistive tech rely on semantic structure.

Keyboard Navigation

All functionality must be operable via keyboard. Tab through interactive elements in logical order. Provide skip links for quick navigation. Users with mobility disabilities depend on this.

Color and Contrast

Don't use color alone to convey information. Ensure text has sufficient contrast (4.5:1 for normal text, 3:1 for large). Colorblind users need non-color cues.

Text Alternatives

Images must have alt text describing content or function. Videos need captions and transcripts. Decorative images use empty alt ("").

Practical Example

# ❌ POOR - No accessibility consideration
from flask import Flask, render_template

@app.route('/checkout')
def checkout():
return '''
<form>
Name: <input type="text">
<input type="submit" value="Submit"> <!-- No label connection -->
<p style="color: red">Required fields have no visual indication</p>
<div onclick="validateForm()">Click here to validate</div>
</form>
'''

# ✅ EXCELLENT - Accessible form with semantic HTML
@app.route('/checkout')
def checkout():
return render_template('checkout.html')

# templates/checkout.html
'''
<form>
<fieldset>
<legend>Shipping Information</legend>

<div class="form-group">
<label for="name">Name <span aria-label="required">*</span></label>
<input
type="text"
id="name"
name="name"
required
aria-required="true"
aria-describedby="name-help"
/>
<small id="name-help">Enter your full name</small>
</div>

<div class="form-group">
<label for="email">Email <span aria-label="required">*</span></label>
<input
type="email"
id="email"
name="email"
required
aria-required="true"
aria-invalid="false"
/>
</div>

<button type="submit" class="btn-primary">
Complete Checkout
</button>
</fieldset>
</form>

<style>
/* Color and contrast */
input {
border: 2px solid #333; /* Good contrast */
padding: 8px;
font-size: 16px;
}

input:focus {
outline: 3px solid #005fcc; /* Visible focus indicator */
outline-offset: 2px;
}

/* Text indication in addition to color */
input[aria-required="true"] ~ small::before {
content: "Required: ";
font-weight: bold;
}

.form-group {
margin-bottom: 1.5em; /* Readable spacing */
}
</style>
'''

Accessibility Patterns

<!-- Allow keyboard users to skip repetitive content -->
<a href="#main" class="skip-link">Skip to main content</a>
<nav>...</nav>
<main id="main">
<!-- Main content -->
</main>

Semantic HTML Structure

<!-- ❌ POOR: Using divs for everything -->
<div class="header">
<div class="nav">
<div onclick="navigate('/')">Home</div>
</div>
</div>

<!-- ✅ GOOD: Semantic structure -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>

ARIA When Needed

<!-- Use ARIA only when semantic HTML isn't sufficient -->
<button aria-expanded="false" aria-controls="menu">
Menu
</button>
<div id="menu" hidden>
<!-- Menu items -->
</div>

<!-- Announce dynamic updates -->
<div aria-live="polite" aria-atomic="true">
Items added to cart: 3
</div>

Color Contrast Checker

function getContrastRatio(color1, color2) {
// WCAG contrast ratio calculation
const luminance1 = getRelativeLuminance(color1);
const luminance2 = getRelativeLuminance(color2);

const lighter = Math.max(luminance1, luminance2);
const darker = Math.min(luminance1, luminance2);

return (lighter + 0.05) / (darker + 0.05);
}

// Test: 4.5:1 for AA compliance for normal text
const ratio = getContrastRatio('#333', '#fff');
console.assert(ratio >= 4.5, `Contrast ratio ${ratio} below WCAG AA`);

Design Review Checklist

  • Is all semantic HTML used correctly (headings, lists, buttons, links)?
  • Can the site be navigated using keyboard only (Tab, Enter, Escape)?
  • Is the focus order logical and visible?
  • Do form fields have associated labels?
  • Is text contrast sufficient (4.5:1 for normal, 3:1 for large)?
  • Are error messages announced to screen readers?
  • Do images have appropriate alt text?
  • Are decorative images hidden from screen readers (alt="")?
  • Do interactive elements have visible focus indicators?
  • Have the site been tested with a screen reader?
  • Can users resize text without breaking layout?
  • Are color-blind users supported (not relying on color alone)?

Self-Check

  1. Navigate your application using only keyboard. Can you reach all interactive elements? Is the order logical?

  2. Open your site in a screen reader (NVDA, JAWS, or Safari/VoiceOver). What does the structure sound like? Is it confusing?

  3. Use a color contrast checker on your most important text. Is it 4.5:1 or better?

One Takeaway

Accessibility isn't a feature or nice-to-have. It's a requirement for inclusive software. Use semantic HTML, ensure keyboard navigation, provide sufficient contrast, and test with real users and assistive technology. Accessibility benefits everyone: captions help in noisy cafes, keyboard navigation benefits power users, clear headings help all users understand structure. Building it in from day one costs less than retrofitting and serves more people.

Next Steps

  • Learn about internationalization ↗ which complements accessibility for global reach
  • Study clear naming ↗ to make interfaces understandable for everyone
  • Review fail-fast ↗ for catching accessibility issues early
  • Explore WCAG 2.1 guidelines at W3C for complete accessibility standards

References

  1. W3C. (2021). Web Content Accessibility Guidelines (WCAG) 2.1. Retrieved from https://www.w3.org/WAI/WCAG21/
  2. MDN Web Docs. (2024). Accessibility. Retrieved from https://developer.mozilla.org/en-US/docs/Web/Accessibility
  3. WebAIM. (2024). Color Contrast Checker. Retrieved from https://webaim.org/resources/contrastchecker/
  4. Horton, S., & Quesenbery, W. (2013). A Web for Everyone. Rosenfeld Media.