Accessibility

Implementation Guide

UVU Web Accessibility Implementation Guide & Checklist

DESIGN NOTE: add form styles...

1. Semantics

Use Proper Headings (<h1> to <h6>) in Logical Order

Why it matters:

  • Headings define the visual and structural hierarchy of your content.
  • They allow screen reader users to navigate quickly by section.
  • Correct nesting (e.g., <h2> under <h1>, <h3> under <h2>) improves accessibility and SEO.

Incorrect Example (Skipped Levels)

<h1>About Us</h1>
<h4>Our Team</h4> <!-- Skips heading levels -->
<h2>Mission</h2>

Correct Example (Logical Nesting)

<h1>About Us</h1>
<h2>Our Team</h2>
<h3>Leadership</h3>
<h2>Mission</h2>

Styling Tip

Style headings with CSS rather than choosing heading tags based on size. Use classes to maintain design flexibility:

<h2 class="fs-xl">Page Title</h2>

HTML Example

  • h1 University Department

    • h2 Faculty

      • h3 Dr. Smith

      • h3 Dr. Jones

    • h2 Programs Offered

      • h3 Undergraduate

      • h3 Graduate

Unlike the < b > tag, which is primarily used for stylistic purposes to apply bold formatting, the < strong > tag carries semantic meaning. While browsers typically render text within < strong > tags in a bold font, the primary purpose of the tag is to provide additional context about the significance of the enclosed text.

Use Structural Tags: <main>, <nav>, <header>, <footer>, <section>, <article>

Why it matters:

  • These tags provide meaning and structure to your page for screen readers and assistive technologies.
  • They define landmarks, allowing users to skip to key parts of the page using assistive tools.
  • They improve SEO and maintainability of your HTML.

Key Structural Elements

  • <main> - The primary content of the page (one per page).
  • <nav> - A section for navigation links.
  • <header> - Introductory content or navigational aids.
  • <footer> - Footer content for a page or section.
  • <section> - A generic section of related content (should typically include a heading).
  • <article> - A self-contained piece of content (e.g., blog post, news story).

Incorrect Example (Using only <div>)

<div id="nav">...</div>
<div class="container">
  <div class="section">
    <h1>Welcome</h1>
  </div>
</div>

Correct Example (Using Semantic Tags)

<header>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<main>
  <section>
    <h1>Welcome to Our Site</h1>
    <p>We provide accessible and inclusive content.</p>
  </section>

  <article>
    <h2>Latest News</h2>
    <p>Our new initiative launches this fall.</p>
  </article>
</main>

<footer>
  <p>© 2025 University Name</p>
</footer>

Use List Tags Appropriately: <ul>, <ol>, <dl>

Why it matters:

  • Lists provide a clear, semantic way to group related items or steps.
  • Screen readers announce the number of items and their structure.
  • Improves content clarity, accessibility, and maintainability.

Types of Lists

  • <ul> - Unordered list (bulleted).
  • <ol> - Ordered list (numbered/steps).
  • <dl> - Description list (terms and definitions).

Incorrect Example (No Semantic List)

<div>Apple</div>
<div>Banana</div>
<div>Cherry</div>

Correct Example (Using <ul>)

<ul>
  <li>Apple</li>
  <li>Banana</li>
  <li>Cherry</li>
</ul>

Correct Example (Using <ol> for Steps)

<ol>
  <li>Download the application.</li>
  <li>Fill out the form.</li>
  <li>Submit your request.</li>
</ol>

Correct Example (Using <dl> for Definitions)

<dl>
  <dt>HTML</dt>
  <dd>A markup language for structuring web content.</dd>
  <dt>CSS</dt>
  <dd>A stylesheet language for styling web pages.</dd>
</dl>

Live HTML Example

Fruits List (Unordered)

  • Apple
  • Banana
  • Cherry

Application Process (Ordered)

  1. Sign up for an account
  2. Complete your profile
  3. Submit the application

Web Terms (Definition List)

DESIGN NOTE: add styles for dl, dt, dd.

ARIA
Accessible Rich Internet Applications, a WAI specification for improved accessibility.
WCAG
Web Content Accessibility Guidelines – standards for making web content more accessible.

2. Keyboard

Ensure All Interactive Elements Are Usable with Tab, Enter, Space, and Arrow Keys

Why it matters:

  • Keyboard navigation is essential for users who can't use a mouse (due to mobility, vision, or other impairments).
  • By default, many native HTML elements are keyboard-accessible - custom components must replicate this behavior.
  • Accessibility standards require that all functionality be available via keyboard input.

Keyboard-Friendly Elements (by default):

  • <a href="#">
  • <button>
  • <input>, <select>, <textarea>
  • Any element with tabindex="0"

Incorrect Example (Missing tabindex and keyboard support):

<div onclick="doSomething()">Click Me</div> <!-- Not focusable or keyboard-operable -->

Correct Example (Using a button):

<button onclick="doSomething()">Click Me</button>

Correct Example (Custom element with tabindex and keyboard events):

<div role="button" tabindex="0" 
     onkeydown="if(event.key==='Enter'||event.key===' ') doSomething()" 
     onclick="doSomething()">
  Click Me
</div>

Best Practice: Keyboard Event Handling (JS Example)

function handleKeyDown(e) {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault();
    doSomething();
  }
}

Live HTML Example

Try tabbing through the items below and pressing Enter or Space:

Custom Keyboard-Enabled Div

Avoid tabindex > 0 to Preserve Natural Focus Order

Why it matters:

  • Setting tabindex="0" makes an element focusable in the natural order of the DOM (good).
  • Setting tabindex="1" or higher overrides the browser’s default tabbing sequence (bad for accessibility).
  • This can cause unpredictable navigation and confusion for keyboard users and assistive technology.

Correct Use of tabindex:

  • tabindex="0" - Add an element to the normal tab order.
  • tabindex="-1" - Make an element focusable via JavaScript (but not with Tab).
  • > 0 - Avoid unless there's a specific and deliberate reason (usually not recommended).

Incorrect Example (tabindex > 0)

<div tabindex="1">First</div>
<div tabindex="3">Third</div>
<div tabindex="2">Second</div>

This creates an unnatural and confusing focus order: 1 → 2 → 3, ignoring DOM order.

Correct Example (tabindex=0, DOM order respected)

<div tabindex="0">First</div>
<div tabindex="0">Second</div>
<div tabindex="0">Third</div>

Correct Example (tabindex=-1 for programmatic focus only)

<div id="popup" tabindex="-1">
  This popup will receive focus via JavaScript only.
</div>

<script>
  document.getElementById('popup').focus();
</script>

Live HTML Example

Tab through the items below. They follow DOM order because they use tabindex="0":

First (tabindex=0)
Second (tabindex=0)
Third (tabindex=0)

Use Skip Links to Allow Users to Jump to Content

Why it matters:

  • Skip links provide keyboard users a quick way to bypass repeated navigation and jump directly to the main content.
  • This is especially important for screen readers and users with mobility impairments.
  • They improve overall usability and are a WCAG requirement under keyboard navigation success criteria.

Requirements:

  • Link should be placed at the top of the document.
  • Must be focusable and visible when focused.
  • Should point to an ID on a main content element (like <main id="main-content">).

Correct Example

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

<nav>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
  </ul>
</nav>

<main id="main-content">
  <h1>Welcome</h1>
  <p>This is the main content of the page.</p>
</main>

Trap Focus in Modals and Return Focus to the Trigger Element

Why it matters:

  • When a modal or dialog opens, keyboard focus should stay inside it (no tabbing outside).
  • When the modal closes, focus should return to the element that opened it.
  • This is critical for screen reader and keyboard users to avoid confusion or loss of context.

Implementation Tips:

  • Use JavaScript to loop tab focus inside the modal.
  • Store the element that triggered the modal, and return focus to it after closing.
  • Use tabindex="-1" and focus() to programmatically manage focus.

Live HTML Example

3. Focus Management & Styles

Use :focus-visible to Style Focused Elements

Why it matters:

  • Focus indicators help keyboard users see where they are on the page.
  • :focus-visible only applies styles when an element is focused via keyboard (not mouse).
  • This improves usability while avoiding visual clutter from unnecessary outlines on click.

What It Does:

  • :focus targets all focused elements (mouse + keyboard).
  • :focus-visible applies only when keyboard (or assistive tech) interaction occurs.

CSS Example

button:focus-visible,
a:focus-visible,
input:focus-visible {
  outline: 3px solid var(--color-focus-ring, #185c33);
  outline-offset: 2px;
  border-radius: 4px;
}

Live HTML Example

Use the Tab key to move through the focusable items below:

Focusable Link

Do Not Remove Focus Outlines Without a Visible Alternative

Why it matters:

  • Focus outlines are the only visual indication of keyboard focus for many users.
  • Removing them without providing an alternative leaves keyboard users disoriented.
  • WCAG requires visible focus indicators for all interactive elements.

Incorrect Example (Accessibility Failure)

button:focus {
  outline: none;
}

This removes the outline entirely, leaving no visual cue for focus.

Correct Example (Accessible Alternative)

button:focus-visible {
  outline: none;
  border: 2px solid var(--color-brand, #185c33);
  box-shadow: 0 0 0 3px rgba(39, 93, 56, 0.4);
  border-radius: 6px;
}

Explanation:

  • outline: none is allowed only if you provide a clear alternative (like box-shadow or border).
  • Use :focus-visible instead of :focus to avoid styling on mouse click.

4. Form Accessibility

Associate Each <label> with an <input>

Why it matters:

  • Proper label association ensures screen readers announce what an input is for.
  • It improves usability for all users, especially those with motor or cognitive impairments.
  • Clicking a label should activate its associated input (e.g., focus the input or toggle a checkbox).

Correct Ways to Associate Labels

  • Use for on the label that matches the id of the input.
  • Or, wrap the input element directly inside the <label> tag (no for needed).

Correct Example (Using for and id)

<label for="email">Email Address</label>
<input type="email" id="email" name="email">

Correct Example (Wrapping Input)

<label>
  Email Address
  <input type="email" name="email">
</label>

Incorrect Example (Not Associated)

<label>Email Address</label>
<input type="email" name="email"> <!-- Not connected -->

Live HTML Example

Group Related Fields Using <fieldset> and <legend>

Why it matters:

  • <fieldset> groups related form inputs together in a semantic block.
  • <legend> provides a descriptive label for that group that is read aloud by screen readers.
  • This is essential for radio buttons, checkboxes, and multi-field inputs like billing info or survey sections.

Correct Example (Grouped Radio Buttons)

<fieldset>
  <legend>Preferred Contact Method</legend>
  <label>
    <input type="radio" name="contact" value="email"> Email
  </label><br>
  <label>
    <input type="radio" name="contact" value="phone"> Phone
  </label>
</fieldset>

Correct Example (Grouped Checkboxes)

<fieldset>
  <legend>Select Your Interests</legend>
  <label><input type="checkbox" name="interest" value="news"> News</label><br>
  <label><input type="checkbox" name="interest" value="events"> Events</label><br>
  <label><input type="checkbox" name="interest" value="updates"> Updates</label>
</fieldset>

Live HTML Example

Preferred Contact Method
Select Your Interests

Use aria-describedby for Validation and Help Text

Why it matters:

  • Screen readers can automatically announce extra context tied to an input field using aria-describedby.
  • This is essential for providing validation errors, help text, and character limits.
  • It connects the input to a visible description element via its id.

Correct Example (Descriptive Help Text)

<label for="username">Username</label>
<input type="text" id="username" aria-describedby="username-help">
<div id="username-help">Must be 6–12 characters long.</div>

Correct Example (Validation Message)

<label for="email">Email</label>
<input type="email" id="email" aria-describedby="email-error">
<div id="email-error" style="color: *see alerts colors;">Please enter a valid email address.</div>

5. Color and Contrast

Use Contrast Ratios of 4.5:1 for Text (AA) or 7:1 (AAA)

Why it matters:

  • Low-contrast text is difficult or impossible to read for users with visual impairments or color blindness.
  • WCAG Level AA requires at least a 4.5:1 contrast ratio for normal text and 3:1 for large text.
  • WCAG Level AAA requires a 7:1 contrast ratio for normal text and 4.5:1 for large text.

How to Check Contrast:

  • Use tools like WebAIM Contrast Checker or browser extensions like axe DevTools or WAVE.
  • Text should be legible in all states (default, hover, focus, active, visited).
  • Check contrast for buttons, links, placeholder text, and graphics with text overlays.

Examples:

High Contrast (Passes WCAG AA)

Black on White - Contrast ratio: 21:1

Low Contrast (Fails WCAG)

Light Grey on White - Contrast ratio: 1.6:1

Large Text with 3:1 Contrast (Passes AA for large text)

Large Text with Acceptable Contrast - Contrast ratio: 3.5:1

CSS Variables for Contrast-Aware Design

:root {
  --color-text-dark: #000000;
  --color-text-light: #ffffff;
  --color-background: #ffffff;
  --color-muted: #666666;
  --color-accent: #185c33;??
}

Live HTML Example

This paragraph passes AA (21:1 contrast).

This paragraph may pass for large text only.

This paragraph fails WCAG contrast.

Provide Non-Color Indicators for Alerts

Why it matters:

  • Colorblind or low-vision users may not perceive color differences clearly.
  • Conveying meaning through color alone (e.g., red = error, green = success) can exclude these users.
  • Accessible alerts should include icons, text labels, shapes, or borders in addition to color.

Accessibility Tip:

  • Always combine color with another cue (text, icon, underline, shape, border).
  • Consider using ARIA roles like role="alert" or role="status" to notify assistive tech.

6. ARIA and Screen Readers

Use ARIA Roles (role="dialog", role="alert") Where Appropriate

Why it matters:

  • ARIA roles give screen readers extra context about what an element is and how to interact with it.
  • They are especially important for custom components that don’t use native HTML semantics.
  • When used correctly, ARIA improves usability for users relying on assistive technologies.

Common ARIA Roles:

  • role="dialog" - Identifies a modal or popup window.
  • role="alert" - Announces important messages immediately.
  • role="status" - Announces updates that do not interrupt the user.
  • role="tooltip" - Marks a tooltip element.
  • role="tablist", role="tab", role="tabpanel" - Define accessible tabs.

Correct Example (Modal Dialog)

<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Newsletter Signup</h2>
  <p>Sign up for updates on new courses.</p>
</div>

Correct Example (Alert Message)

<div role="alert">
  ⚠Your session is about to expire.
</div>

Correct Example (Live Status Update)

<div role="status" aria-live="polite">
  Your settings were saved.
</div>

Accessibility Tip:

  • Do not use ARIA to replicate things that native HTML already supports (e.g., use <button> instead of <div role="button"> when possible).
  • ARIA adds power - but misusing it can confuse screen readers. Use with care.

Use aria-expanded, aria-live, aria-hidden for Dynamic Content

Why it matters:

  • These ARIA attributes notify screen readers when content changes or becomes visible/hidden.
  • They provide important state information that is otherwise invisible to assistive technology users.
  • Without these attributes, dynamic interactions like dropdowns or alerts may not be communicated properly.

Attribute Use Cases:

  • aria-expanded - Indicates whether collapsible content is open or closed.
  • aria-live - Announces content changes automatically.
  • aria-hidden - Hides elements from screen readers (without affecting visual layout).

Correct Example: Collapsible Section

<button aria-expanded="false" aria-controls="more-info" onclick="togglePanel()">
  Show More
</button>
<div id="more-info" hidden>
  <p>Here is some additional information.</p>
</div>

Correct Example: Live Region

<div id="form-status" role="status" aria-live="polite">
  Your profile has been saved.
</div>

Correct Example: Visually Hidden but Screen Reader Ignored

<div aria-hidden="true">
  Decorative content that should not be read aloud.
</div>

Live HTML Example

Status: This message will be read automatically.

Accessibility Tip:

  • Update aria-expanded on toggle buttons whenever the state changes.
  • Use aria-live sparingly and appropriately (e.g., only for status or error messages).
  • Do not rely on aria-hidden to manage visibility - pair it with visual hiding techniques if necessary.

7. Responsive and Scalable Design

Use Flexible Units: em, rem, %

Why it matters:

  • Fixed pixel (px) values do not scale well for users with zoom preferences or custom text sizing.
  • Relative units like rem and em respect the user's browser or OS-level font settings.
  • Flexible units create responsive layouts that adjust across devices, screen sizes, and accessibility settings.

Common Flexible Units:

  • rem: Root em - scales from the root <html> font size.
  • em: Relative to the parent element's font size.
  • %: Useful for fluid widths, padding, and heights.
  • clamp(): Dynamic scaling between a min and max value.

Incorrect Example (Fixed Pixel Sizing)

h1 {
  font-size: 24px;
  padding: 20px;
}

Correct Example (Relative and Fluid Sizing)

h1 {
  font-size: 1.5rem;
  padding: 2%;
}

.container {
  width: 100%;
  max-width: 60rem;
  margin: 0 auto;
}

Example Using clamp() for Font Responsiveness

p {
  font-size: clamp(1rem, 2vw, 1.25rem);
}

Accessibility Tip:

  • Set the base font size on the <html> element with font-size: 100% to allow proper scaling.
  • Use rem for consistent global typography and spacing.
  • Use em for component-level adjustments.

Allow Zoom Up to 200% Without Content Loss

Why it matters:

  • Many users rely on browser zoom to enlarge content instead of using screen magnifiers.
  • WCAG 2.1 requires that content remains usable and readable up to 200% zoom without horizontal scrolling (except where unavoidable, like data tables).
  • Text, layout, and UI should reflow or stack properly at increased zoom levels.

Best Practices:

  • Use a responsive layout (Flexbox, Grid, percentage widths).
  • Avoid fixed heights/widths in px that constrain resizing.
  • Allow line wrapping and stacking for text and elements.
  • Use media queries or container queries for better breakpoint control.

Incorrect Example (Zoom Causes Overflow)

.fixed-box {
  width: 960px;
  height: 400px;
  overflow: hidden;
}

Correct Example (Responsive Layout)

.responsive-box {
  max-width: 100%;
  padding: 1rem;
  box-sizing: border-box;
  word-wrap: break-word;
}

Accessibility Tip:

  • Always test your layouts at 200% zoom to verify that content reflows and is still usable.
  • Use browser DevTools (emulation mode) to simulate zoom and small screen environments.
  • Text should never be clipped, overlapped, or hidden when zoomed in.

Avoid Fixed Pixel Dimensions for Critical Text and Containers

Why it matters:

  • Fixed px dimensions restrict flexibility and can cause overflow or cutoff content when users zoom.
  • Responsive content needs to reflow and resize based on screen size, zoom level, and user preferences.
  • Critical content - like paragraphs, buttons, and forms - should expand naturally within their containers.

Problem with Fixed Widths:

.text-box {
  width: 400px;
  height: 200px;
  font-size: 16px;
}

This limits scalability and may truncate content when zoomed or viewed on smaller screens.

Recommended Responsive Approach:

.text-box {
  max-width: 100%;
  width: auto;
  padding: 1rem;
  font-size: 1rem;
  box-sizing: border-box;
}

Use Relative Dimensions for Layouts

.container {
  width: 100%;
  max-width: 60rem;
  margin: 0 auto;
}

Accessibility Tip:

  • Use max-width, width: 100%, or auto to support reflow.
  • Avoid height restrictions unless necessary - let content define container height.
  • Combine responsive techniques with media queries for better control across breakpoints.

8. Motion & Animation

Respect prefers-reduced-motion User Preferences

Why it matters:

  • Animations and transitions can trigger discomfort, nausea, or seizures for users with motion sensitivity or vestibular disorders.
  • WCAG requires you to provide an option to disable motion or respect system-level preferences.
  • The prefers-reduced-motion media query allows you to automatically reduce or remove animations for users who request it.

Best Practices:

  • Remove non-essential animations, or shorten durations significantly.
  • Avoid large-scale or parallax motion effects unless user-triggered.
  • Use prefers-reduced-motion to customize motion behavior.

Basic CSS Example (Respecting Motion Preference)

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001s !important;
    transition-duration: 0.001s !important;
  }
}

Optional Example (Turn Off Specific Effects)

@media (prefers-reduced-motion: reduce) {
  .background-fade,
  .slide-in,
  .zoom-effect {
    animation: none !important;
    transition: none !important;
  }
}

Live HTML Example

This paragraph has a simple fade-in animation that can be turned off by prefers-reduced-motion.

Accessibility Tip:

  • Test with OS accessibility settings enabled to simulate reduced motion.
  • Use animation-play-state: paused or animation: none for full motion cutoff.
  • Let users opt out of optional animations through interface settings or toggles when appropriate.

9. Multimedia

Provide Captions and Transcripts for Multimedia

Why it matters:

  • Captions and transcripts make video and audio content accessible to users who are deaf, hard of hearing, or prefer text-based content.
  • They improve comprehension for non-native speakers, users in noisy environments, or when audio can’t be played.
  • WCAG requires synchronized captions for videos with audio and transcripts for audio-only content.

Types of Accessibility Support:

  • Captions: Timed text that appears on video, describing spoken dialogue and important sounds.
  • Transcripts: Full-text versions of spoken content (and sometimes visual info) for audio or video.
  • Audio Descriptions: Narration describing important visual events for users who are blind.

Correct Example: Video with Captions

<video controls>
  <source src="sample.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en" label="English" default>
  Your browser does not support the video tag.
</video>

Correct Example: Audio with Transcript

<audio controls>
  <source src="podcast.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

<div>
  <h3>Transcript</h3>
  <p>[Host]: Welcome to the podcast...</p>
  <p>[Guest]: Thanks for having me...</p>
</div>

Live HTML Example

Video with Captions:

Add video sample...

Transcript Example (for Audio or Video):

Transcript

[Host]: Welcome to our show.


[Guest]: Thanks for having me. Today we’ll explore how to build accessible websites.

Accessibility Tip:

  • Always provide <track kind="captions"> with proper language and labeling.
  • Include transcripts next to audio-only content or when captions aren’t feasible.
  • Make sure captions are accurate, complete, and synchronized with the audio.

Use Audio Descriptions for Visual Information

Why it matters:

  • Blind and low-vision users rely on audio descriptions to understand what is happening visually in a video.
  • Standard dialogue and sound effects may not describe important actions, facial expressions, or on-screen text.
  • WCAG requires audio descriptions for prerecorded video content where visual context is essential to understanding.

What Are Audio Descriptions?

  • Narration added to a video to describe key visual elements.
  • Often played in pauses between dialogue, or in an alternate version of the video.
  • Can be delivered via a separate audio track or embedded in the main video.

Correct Example (Separate Descriptive Audio Track)

<video controls>
  <source src="video-with-descriptions.mp4" type="video/mp4">
  <track kind="descriptions" src="descriptions.vtt" srclang="en" label="Audio Description">
</video>

Alternative Method: Described Video Version

<a href="video-described.mp4">Watch Described Video Version</a>

Example Transcript with Visual Descriptions

Transcript (with Visual Descriptions)

[Narrator]: A young woman walks into a sunlit library, holding a stack of books.


[Host]: Welcome to our digital literacy program.

Accessibility Tip:

  • Provide a separate version of the video that includes narration of visual elements.
  • If you can't include audio descriptions in the video, provide a detailed transcript that includes visual cues.
  • Use kind="descriptions" in <track> when supported, or clearly label alternate versions.

10. Navigation & Landmarks

Use <header>, <main>, <footer> Landmarks

Why it matters:

  • Landmark elements allow screen reader and keyboard users to jump to key areas of a page easily.
  • They define page structure semantically without relying on ARIA roles (though ARIA roles can supplement them).
  • They help all users understand and scan the layout of your page, especially on long or complex sites.

Common Landmark Elements:

  • <header> - Top section of the page or a section; typically includes branding, logo, and navigation.
  • <nav> - Main or secondary navigation links.
  • <main> - The primary content of the page. Only one per page.
  • <aside> - Supplementary information, like a sidebar or callout.
  • <footer> - Footer for the page or a section; includes copyright, links, etc.

Correct Example (Semantic Layout with Landmarks)

<header>
  <h1>Site Title</h1>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<main id="main-content">
  <h2>Welcome</h2>
  <p>This is the primary content of the page.</p>
</main>

<footer>
  <p>© 2025 Accessibility Example</p>
</footer>

Accessibility Tip:

  • Use each landmark appropriately and only once where required (e.g., only one <main> per page).
  • For older browsers or screen readers, you can add ARIA roles as fallbacks (e.g., role="main", role="navigation").
  • Make sure the landmark content has a clear heading structure inside it.

11. Testing & Auditing

Conduct a Keyboard-Only Test

Why it matters:

  • Many users rely solely on the keyboard (e.g., users with motor impairments, screen reader users).
  • A keyboard-only test ensures that all functionality (navigation, forms, modals, toggles) is accessible without a mouse.
  • It's one of the fastest and most effective ways to catch major accessibility barriers.

How to Perform a Keyboard Test:

  1. Unplug your mouse or trackpad - or simply avoid using it.
  2. Use Tab to move forward through interactive elements (links, buttons, form inputs).
  3. Use Shift + Tab to move backward.
  4. Press Enter or Space to activate links and buttons.
  5. Use arrow keys to navigate menus, sliders, and other widgets when applicable.

What to Check For:

  • Can you access every interactive element using only the keyboard?
  • Does focus move logically and visibly?
  • Are dropdowns, modals, and menus operable with keyboard controls?
  • Are there any focus traps or places where focus gets “stuck” or lost?

Live Test Area

Focusable Link

Accessibility Tip:

  • Focus outlines should always be visible when using the keyboard - if not, ensure :focus-visible styles are applied.
  • Form controls should be operable with Tab, Enter, Space, and arrow keys where applicable.
  • Every page should be fully navigable without requiring a mouse.

Test with Screen Readers (NVDA, VoiceOver, etc.)

Why it matters:

  • Screen readers interpret HTML and ARIA for users who are blind or visually impaired.
  • Only by testing with a screen reader can you ensure your content is being announced clearly and in the right order.
  • Different screen readers and browsers behave differently - testing with at least one is essential.

Popular Screen Readers:

  • NVDA (Windows, free)
  • JAWS (Windows, paid)
  • VoiceOver (macOS and iOS, built-in)
  • TalkBack (Android, built-in)

How to Perform a Screen Reader Test:

  1. Enable the screen reader on your system (e.g., VoiceOver on Mac: Cmd + F5)
  2. Navigate through your page using the keyboard and listen to what’s announced.
  3. Use heading navigation (H key), landmarks, tab order, and form control navigation.
  4. Ensure all links, buttons, and controls are described clearly.
  5. Check for correct reading order and meaningful alt text or labels.

Accessibility Tip:

  • Listen for vague or missing labels - e.g., “button” without context is not helpful.
  • Ensure screen readers do not read unnecessary elements (hide with aria-hidden="true" if needed).
  • Announce dynamic changes using aria-live regions to keep users informed.

Use Accessibility Tools: axe DevTools, Lighthouse, WAVE

Why it matters:

  • Automated tools help quickly identify many common accessibility issues.
  • They complement - but do not replace - manual testing like keyboard or screen reader use.
  • Running regular audits helps catch regressions and maintain compliance with WCAG guidelines.

Popular Tools:

  • axe DevTools (browser extension by Deque Systems)
  • Lighthouse (built into Chrome DevTools)
  • WAVE (Web Accessibility Evaluation Tool by WebAIM)
  • Siteimprove Accessibility Checker (Chrome plugin)
  • Silktide Accessibility Checker (browser extension)

How to Use Them:

  1. Install one of the browser extensions or use built-in Lighthouse in Chrome DevTools.
  2. Open the page in your browser, run the audit, and review the report.
  3. Fix issues like missing alt text, poor contrast, missing labels, ARIA misuse, and more.
  4. Repeat testing after changes and during major site updates.

Example: Running Lighthouse

1. Open Chrome DevTools (F12 or Right Click → Inspect)
2. Go to the Lighthouse tab
3. Select "Accessibility" and click "Analyze page load"
4. Review and address the issues shown in the report

Accessibility Tip:

  • Automated tools typically catch about 30–50% of accessibility issues - always combine with manual testing.
  • Use these tools regularly during development - not just before launch.
  • Fix color contrast, form labeling, missing alt attributes, and ARIA misusage as flagged.