Web Accessibility Basics-Building Accessible Front-End Applications

Tianya SchoolTianya School
5 min read

Web Accessibility ensures that websites and applications are equally usable by everyone, including those with visual, auditory, motor, or cognitive impairments. Below are foundational principles and code examples for building accessible front-end applications.

1. Text Alternatives (alt Attribute)

Provide descriptive alt attributes for non-text content (e.g., images) to enable screen reader users to understand the content.

<img src="hero.jpg" alt="A smiling person holding a cup of coffee">

2. Labels and Roles (ARIA Roles)

Use ARIA (Accessible Rich Internet Applications) roles and attributes to enhance accessibility, especially for complex interactive elements.

<button role="button" aria-label="Close">X</button>

3. Form Elements

Ensure form elements have clear labels, associating <label> with <input> elements.

<label for="email">Email:</label>
<input type="email" id="email" required>

4. Keyboard Navigation

All interactive elements should be navigable via keyboard, following a natural focus order.

<nav>
  <ul>
    <li><a href="#home" tabindex="0">Home</a></li>
    <li><a href="#about" tabindex="0">About</a></li>
    <li><a href="#contact" tabindex="0">Contact</a></li>
  </ul>
</nav>

5. Color Contrast

Ensure sufficient color contrast between text and background, avoiding color as the sole means of conveying information.

/* Use tools like WCAG Color Contrast Checker */
body {
  color: #000; /* dark text */
  background-color: #f8f8f8; /* light background, good contrast */
}

6. Visually Hidden Content

Use a visually-hidden class to hide content visually while keeping it accessible to screen readers.

.visually-hidden {
  position: absolute !important;
  clip: rect(0 0 0 0) !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  border: 0 !important;
}
<button>
  <span class="visually-hidden">Skip to main content</span>
  Skip
</button>

7. ARIA Live Regions

Use the aria-live attribute to notify screen reader users of dynamic page updates.

<div aria-live="polite" aria-atomic="true" class="notification">
  <!-- Dynamic content will be inserted here -->
</div>

8. Time-Sensitive Content

Provide deadlines or timers for time-sensitive content.

<p>
  This offer expires in:
  <span id="countdown"></span>
</p>

<script>
  // Update countdown element content
</script>

9. Touch Device Considerations

Ensure touch targets are at least 44x44 pixels and avoid overly tight layouts.

.button {
  min-width: 44px;
  min-height: 44px;
  padding: 10px;
}

10. Semantic Coding

Use semantic HTML elements like <header>, <nav>, <main>, <article>, <section>, and <footer>.

<body>
  <header>
    <!-- Header content -->
  </header>
  <main>
    <!-- Main content -->
  </main>
  <footer>
    <!-- Footer content -->
  </footer>
</body>

11. Visual Indicators

Add visual feedback for interactive elements, such as hover, focus, and active states.

.button {
  transition: all 0.3s;
}

.button:hover,
.button:focus,
.button:active {
  background-color: #333;
  color: #fff;
}

12. Voice Commands and Input

Support voice-controlled devices (e.g., Siri, Google Assistant) by ensuring interfaces are operable via voice commands.

<form action="/search">
  <label for="search">Search:</label>
  <input type="search" id="search" name="q" placeholder="Voice command: Search...">
  <button type="submit">Go</button>
</form>

13. Font and Text Readability

Choose readable fonts with sufficient line height, letter spacing, and font size. Ensure text scaling doesn’t break layouts.

body {
  font-family: Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0.05em;
  text-rendering: optimizeLegibility;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}

14. Clear State for Interactive Elements

Ensure users know when elements are interactive and their interaction state.

input[type="checkbox"]:checked + label::before {
  content: '\2713'; /* checkmark character */
}
<input type="checkbox" id="accept" />
<label for="accept">I accept the terms and conditions</label>

15. Colorblind Users

Use color contrast checkers to ensure color combinations are friendly for colorblind users.

.colorblind-friendly {
  background-color: #008080;
  color: #fff;
}

16. Visual Aids

Provide visual aids like magnifiers, high-contrast modes, or colorblind simulators.

<button id="toggle-high-contrast">Toggle High Contrast</button>

<script>
  document.getElementById('toggle-high-contrast').addEventListener('click', function() {
    document.body.classList.toggle('high-contrast');
  });
</script>

<style>
  .high-contrast {
    background-color: #000;
    color: #fff;
  }
</style>

17. Screen Reader Compatibility

Ensure all critical information is readable by screen readers, such as table captions and summaries.

<table>
  <caption>Employee List</caption>
  <thead>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
    </tr>
  </thead>
  <!-- Table rows -->
</table>

18. Responsive Design

Ensure the website performs well across devices and screen sizes, accommodating various access methods.

@media (max-width: 768px) {
  /* Mobile-specific styles */
}

19. Video and Audio Content

Provide captions for videos and transcripts for audio.

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

20. Regular Testing

Use automated and manual testing tools (e.g., axe, Pa11y, Lighthouse) to regularly check accessibility and improve based on feedback.

21. Image Maps

For images with multiple interactive regions, use image maps to provide clickable areas.

<img src="worldmap.png" usemap="#worldmap" alt="World Map">
<map name="worldmap">
  <area shape="rect" coords="0,0,82,126" alt="North America" href="#na">
  <area shape="circle" coords="200,100,30" alt="Europe" href="#eu">
  <area shape="poly" coords="330,50,380,0,450,50,400,100" alt="Asia" href="#as">
</map>

22. Text-to-Speech

Offer text-to-speech options to allow users to hear page content.

<button id="tts">Read Aloud</button>

<script>
  document.getElementById('tts').addEventListener('click', function() {
    const textToRead = document.querySelector('main').innerText;
    const speech = new SpeechSynthesisUtterance(textToRead);
    window.speechSynthesis.speak(speech);
  });
</script>

23. Error Messages and Feedback

Provide clear error messages and feedback to help users resolve issues.

<form>
  <label for="email">Email:</label>
  <input type="email" id="email" required>
  <span id="email-error" class="error"></span>
  <button type="submit">Submit</button>
</form>

<script>
  document.querySelector('form').addEventListener('submit', function(event) {
    event.preventDefault();
    const emailInput = document.getElementById('email');
    const errorSpan = document.getElementById('email-error');

    if (!emailInput.checkValidity()) {
      errorSpan.textContent = 'Please enter a valid email address.';
    } else {
      errorSpan.textContent = '';
      // Submit form or perform other actions
    }
  });
</script>

24. Focus Management for Interactive Elements

Ensure keyboard focus flows correctly between elements, avoiding skips or duplicates.

const focusableElements = 'a[href], button, input:not([type="hidden"]), textarea, select, iframe, object, embed, [tabindex="0"], [contenteditable]';
const firstFocusableElement = document.querySelector(focusableElements);

document.addEventListener('DOMContentLoaded', function() {
  if (firstFocusableElement) {
    firstFocusableElement.focus();
  }
});

document.addEventListener('keydown', function(event) {
  if (event.key === 'Tab') {
    const lastFocusableElement = document.querySelector(`${focusableElements}:last-of-type`);
    if (event.shiftKey && document.activeElement === document.body) {
      lastFocusableElement.focus();
      event.preventDefault();
    } else if (!event.shiftKey && document.activeElement === lastFocusableElement) {
      firstFocusableElement.focus();
      event.preventDefault();
    }
  }
});
0
Subscribe to my newsletter

Read articles from Tianya School directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tianya School
Tianya School

❤️ • Full Stack Developer 🚀 • Building Web Apps 👨‍💻 • Learning in Public 🤗 • Software Developer ⚡ • Freelance Dev 💼 • DM for Work / Collabs 💬