Skip to content

paras594/web-accessibility-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Web Accessibility Guide

Web Accessibility

A reference guide to web accessibility best practices and implementation.

Refer the repo code for the keyboard accessibility examples.

Live Link

"If a website or part of a website works only with a mouse, then it's not accessible"

WHY IT MATTERS?

The web should empower people, not frustrate or isolate them. Accessibility ensures that no one is locked out of opportunities simply because of how they interact with technology.

Accessibility is about empathy β€” imagining yourself in someone else’s place and choosing to build a world that doesn’t leave them behind.

Table of Contents

  1. Disabilities
  2. Semantic HTML ⭐
  3. Color Contrast ⭐
  4. Text Alternatives (Alt Text)
  5. Form Accessibility
  6. Heading Structure
  7. Link Accessibility
  8. Focus Management ⭐
  9. Language Attributes
  10. Responsive Design & Viewport
  11. Motion & Animation Preferences
  12. Error Handling & Validation
  13. Time-Based Media
  14. Tables
  15. Landmarks & Regions
  16. Performance
  17. Testing Checklist ⭐
  18. WCAG 2.1 Principles
  19. Priority Order for Implementation ⭐

0. Disabilities

  • Visual: Users who have low vision, color blindness, or blindness. Screen readers, proper color contrast, scalable texts etc. help them.
  • Auditory: Users who are deaf or hard of hearing. Captions, transcripts, and visual cues help them.
  • Physical: Users with limited motor control, tremors, paralysis, or who cannot use a mouse. Keyboard navigation, large clickable areas, etc. help them
  • Cognitive: Users with learning difficulties, memory issues, ADHD, dyslexia, etc. Simple language, consistent layout, clear navigation helps them.
  • Neurological: Users affected by epilepsy, migraines, or other neurological conditions. Avoid flashy or animated content, allow motion reduction and have predictable interactions.

1. Semantic HTML

Use the right HTML elements for their purpose. Screen readers and browsers understand structure and meaning.

Good Example:

<header>
  <nav aria-label="Main navigation">
    <ul>
      <li><a href="/">Home</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h1>Article Title</h1>
    <p>Content...</p>
  </article>
</main>
<footer>Footer content</footer>

Bad Example:

<div class="header">
  <div class="nav">
    <div><a href="/">Home</a></div>
  </div>
</div>

Key semantic elements: <header>, <nav>, <main>, <article>, <section>, <aside>, <footer>, <button>, <form>, <label>, etc.


2. Color Contrast

Ensure text meets WCAG contrast requirements.

WCAG Standards:

  • Level AA: 4.5:1 for normal text, 3:1 for large text
  • Level AAA: 7:1 for normal text, 4.5:1 for large text

Bad Example:

<p style="color: #ccc; background: #fff;">Hard to read</p>

Good Example:

<p style="color: #000; background: #fff;">Easy to read</p>

Tools: WebAIM Contrast Checker, axe DevTools, browser DevTools

Important: Don't rely on color alone

Bad:

<span style="color: red;">Error</span>

Good:

<span style="color: red;" aria-label="Error">
  ⚠️ Error: Invalid input
</span>

3. Text Alternatives (Alt Text)

Provide meaningful alt text for images.

Good Examples:

<!-- Descriptive alt text -->
<img src="chart.jpg" alt="Sales increased 25% from Q1 to Q2 2024" />

<!-- Decorative images -->
<img src="decoration.jpg" alt="" />

<!-- Complex images with longer description -->
<img src="diagram.jpg" alt="Process flow diagram" />
<figcaption>
  Detailed description: The process starts with user input, 
  goes through validation, then processing...
</figcaption>

Guidelines:

  • Be specific and concise
  • Describe the purpose, not just appearance
  • Use empty alt="" for decorative images
  • Provide longer descriptions for complex images

4. Form Accessibility

Make forms accessible with proper labels, error handling, and instructions.

Good Example:

<form>
  <fieldset>
    <legend>Contact Information</legend>
    
    <label for="email">
      Email Address
      <span aria-label="required">*</span>
    </label>
    <input 
      type="email" 
      id="email"
      name="email"
      aria-required="true"
      aria-describedby="email-help email-error"
    />
    <div id="email-help">We'll never share your email</div>
    <div id="email-error" role="alert" aria-live="polite"></div>
    
    <label for="phone">Phone Number</label>
    <input 
      type="tel" 
      id="phone"
      name="phone"
      aria-describedby="phone-format"
    />
    <div id="phone-format">Format: (555) 123-4567</div>
  </fieldset>
  
  <button type="submit">Submit</button>
</form>

Key Points:

  • Always use <label> elements
  • Group related fields with <fieldset> and <legend>
  • Provide clear error messages
  • Use aria-required, aria-invalid, aria-describedby
  • Associate help text with inputs

5. Heading Structure

Use a logical heading hierarchy.

Good Example:

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

Bad Example:

<h1>Main Title</h1>
  <h3>Skipped h2!</h3> <!-- Don't skip h2 -->

Rules:

  • One <h1> per page
  • Don't skip heading levels
  • Use headings to structure content, not for styling

6. Link Accessibility

Make links descriptive and distinguishable.

Bad Examples:

<a href="/page">Click here</a>
<a href="/page">Read more</a>

Good Examples:

<a href="/page">Learn about our accessibility features</a>
<a href="/page">Read the full article about web accessibility</a>

<!-- Links that open in new window -->
<a 
  href="/external" 
  target="_blank"
  rel="noopener noreferrer"
  aria-label="Opens in new window"
>
  External Resource
</a>

Best Practices:

  • Use descriptive link text
  • Indicate when links open in new windows
  • Make links visually distinct (not just color)
  • Provide skip links for navigation

7. Focus Management

Manage focus for dynamic content and modals.

Skip to Main Content Link:

<a href="#main-content" class="skip-link">Skip to main content</a>

<style>
  .skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: #000;
    color: #fff;
    padding: 8px;
    text-decoration: none;
  }
  .skip-link:focus {
    top: 0;
  }
</style>

<main id="main-content">
  <!-- Content -->
</main>

Modal Focus Trapping:

// Trap focus within modal
function trapFocus(modal) {
  const focusableElements = modal.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const firstElement = focusableElements[0];
  const lastElement = focusableElements[focusableElements.length - 1];

  modal.addEventListener('keydown', (e) => {
    if (e.key === 'Tab') {
      if (e.shiftKey) {
        if (document.activeElement === firstElement) {
          e.preventDefault();
          lastElement.focus();
        }
      } else {
        if (document.activeElement === lastElement) {
          e.preventDefault();
          firstElement.focus();
        }
      }
    }
  });
}

8. Language Attributes

Specify the page language and language changes.

<html lang="en">
  <head>
    <title>My Page</title>
  </head>
  <body>
    <p>This is in English.</p>
    <p lang="es">Esto estΓ‘ en espaΓ±ol.</p>
    <p lang="fr">Ceci est en franΓ§ais.</p>
  </body>
</html>

9. Responsive Design & Viewport

Ensure content works on all screen sizes.

<meta name="viewport" content="width=device-width, initial-scale=1" />

Considerations:

  • Text should be readable without zooming
  • Touch targets should be at least 44x44px
  • Content should reflow properly
  • Avoid horizontal scrolling

10. Motion & Animation Preferences

Respect user preferences for reduced motion.

/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Or disable specific animations */
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation: none;
  }
}

11. Error Handling & Validation

Provide clear, accessible error messages.

<form>
  <label for="email">Email</label>
  <input 
    type="email" 
    id="email"
    aria-invalid="false"
    aria-describedby="email-error"
    aria-required="true"
  />
  <div 
    id="email-error" 
    role="alert"
    aria-live="polite"
    class="error-message"
  >
    <!-- Error message appears here -->
  </div>
</form>

<script>
  function validateEmail(input) {
    const errorDiv = document.getElementById('email-error');
    const isValid = input.validity.valid;
    
    input.setAttribute('aria-invalid', !isValid);
    
    if (!isValid) {
      errorDiv.textContent = 'Please enter a valid email address';
      errorDiv.style.display = 'block';
    } else {
      errorDiv.textContent = '';
      errorDiv.style.display = 'none';
    }
  }
</script>

12. Time-Based Media

Provide captions, transcripts, and audio descriptions.

<video controls>
  <source src="video.mp4" type="video/mp4" />
  <track 
    kind="captions" 
    src="captions.vtt" 
    srclang="en" 
    label="English"
    default
  />
  <track 
    kind="descriptions" 
    src="descriptions.vtt" 
    srclang="en"
  />
</video>

<audio controls>
  <source src="audio.mp3" type="audio/mpeg" />
  <a href="transcript.txt">Transcript available</a>
</audio>

13. Tables

Make tables accessible with proper structure.

<table>
  <caption>Monthly Sales Report</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Sales</th>
      <th scope="col">Growth</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">January</th>
      <td>$10,000</td>
      <td>+5%</td>
    </tr>
  </tbody>
</table>

14. Landmarks & Regions

Use ARIA landmarks to identify page regions.

<header role="banner">
  <!-- Site header -->
</header>

<nav role="navigation" aria-label="Main navigation">
  <!-- Navigation -->
</nav>

<main role="main">
  <!-- Main content -->
</main>

<aside role="complementary" aria-label="Related articles">
  <!-- Sidebar -->
</aside>

<footer role="contentinfo">
  <!-- Footer -->
</footer>

15. Performance

Fast loading benefits all users, especially those on slower connections.

Considerations:

  • Optimize images
  • Minimize JavaScript
  • Use lazy loading
  • Provide loading states
  • Ensure critical content loads first

16. Testing Checklist

Automated Tools:

  • axe DevTools - Browser extension for accessibility testing
  • WAVE - Web Accessibility Evaluation Tool
  • Lighthouse - Built into Chrome DevTools
  • Pa11y - Command-line accessibility testing

Manual Testing:

  • βœ… Keyboard-only navigation
  • βœ… Screen reader testing (NVDA, JAWS, VoiceOver)
  • βœ… Color contrast checking
  • βœ… Zoom testing (up to 200%)
  • βœ… Mobile device testing

WCAG 2.1 Principles

The Web Content Accessibility Guidelines (WCAG) are organized around four principles:

1. Perceivable - Information must be presentable to users

  • Text alternatives, captions, color contrast, text resizing

2. Operable - Interface components must be operable

  • Keyboard accessible, no seizures, navigable, enough time

3. Understandable - Information must be understandable

  • Readable, predictable, input assistance

4. Robust - Content must be robust enough for assistive technologies

  • Valid HTML, proper use of ARIA, compatible with tools

Priority Order for Implementation

1. Critical (Start Here)

  • Semantic HTML
  • Keyboard navigation
  • Focus management

2. High Priority

  • Color contrast
  • Alt text
  • Form labels
  • Heading structure

3. Important

  • ARIA labels
  • Error handling
  • Skip links
  • Language attributes

4. Enhancement

  • Motion preferences
  • Captions
  • Advanced ARIA patterns

Additional Resources


Quick Reference: ARIA Attributes

Common ARIA Attributes:

  • aria-label - Provides an accessible name
  • aria-labelledby - References elements that label this element
  • aria-describedby - References elements that describe this element
  • aria-hidden - Hides element from assistive technologies
  • aria-expanded - Indicates expandable/collapsible state
  • aria-controls - Identifies controlled elements
  • aria-live - Indicates live region (polite, assertive, off)
  • aria-required - Indicates required form field
  • aria-invalid - Indicates invalid input
  • aria-current - Indicates current item in set

Remember: Start with the basics (semantic HTML, keyboard navigation, proper labels) and build from there. Each improvement makes your site more accessible to everyone!

About

A small but focused repository to help build a more inclusive web. It contains HTML, CSS, and JavaScript examples for keyboard navigation and a README covering essential web accessibility guidelines.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors