Accessibility

Implementation Guide

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 (for example, <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 Web Guide type utilities such as .fs-* for design flexibility.

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

Live HTML Example

  • h1 University Department

    • h2 Faculty

      • h3 Dr. Smith

      • h3 Dr. Jones

    • h2 Programs Offered

      • h3 Undergraduate

      • h3 Graduate

<strong> vs <b>

Unlike <b>, which is primarily visual styling, <strong> carries semantic meaning. Browsers often render both as bold, but assistive technologies treat <strong> as emphasized importance.

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

Why it matters:

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

Key Structural Elements

  • <nav> - A section for navigation links.
  • <header> - Introductory content or navigational aids.
  • <footer> - Footer content for a page or section.
  • <section> - A section of related content that should usually have its own heading.
  • <article> - A self-contained piece of content such as a post, story, or update.

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>

<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>

<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.
  • They improve content clarity, accessibility, and maintainability.

Types of Lists

  • <ul> - Unordered list.
  • <ol> - Ordered list for steps or sequence.
  • <dl> - Description list for 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 cannot use a mouse.
  • Native HTML controls are keyboard-accessible by default; custom components must match that behavior.
  • Accessibility standards require that all functionality is available from the keyboard.

Keyboard-friendly elements (by default):

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

Incorrect Example (not focusable, no keyboard support)

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

Correct Example (use a button)

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

Correct Example (custom element with tabindex + 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 Element

Avoid tabindex > 0 to Preserve Natural Focus Order

Why it matters:

  • tabindex="0" adds an element to the normal tab order.
  • tabindex="1" or higher overrides the browser’s default order and usually creates confusion.
  • This can make keyboard navigation harder for users and assistive technologies.

Correct uses:

  • tabindex="0" — focusable in normal DOM order
  • tabindex="-1" — focusable only with JavaScript
  • > 0 — avoid unless there is a very specific reason

Incorrect Example (tabindex > 0)

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

Correct Example (DOM order respected)

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

Live HTML Example

Tab through the items below. They follow DOM order:

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

Use Skip Links to Allow Users to Jump to Content

Why it matters:

  • Skip links give keyboard users a quick way to bypass repeated navigation.
  • They should be the first focusable item on the page and become visible on focus.
  • They should target the main content container for the page.

Correct Example

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

<nav>...</nav>

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

Trap Focus in Modals and Return Focus to the Trigger Element

Why it matters:

  • When a modal opens, keyboard focus should stay inside it.
  • When the modal closes, focus should return to the trigger element.
  • This prevents keyboard users from getting lost behind the overlay.

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 is the right pattern for keyboard-focused states.
  • This improves usability while avoiding extra outlines on every mouse click.

CSS Example

a:focus-visible,
button:focus-visible,
input:focus-visible {
  outline: var(--color-wolverine-green) auto 2px !important;
}

Live HTML Example

Use the Tab key to move through the items below:

Focusable Link

Do Not Remove Focus Outlines Without a Visible Alternative

Why it matters:

  • Focus outlines are often the only visual indicator of keyboard focus.
  • Removing them without a strong replacement leaves keyboard users disoriented.
  • WCAG requires visible focus indicators for interactive elements.

Incorrect Example

button:focus {
  outline: none;
}

Correct Example (visible alternative)

button:focus-visible {
  outline: none;
  border-color: var(--color-uvu-green);
  box-shadow: 0 0 0 3px rgba(var(--color-uvu-green-rgb), 0.3);
}

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.

Correct Ways to Associate Labels

  • Use for on the label that matches the id of the input.
  • Or wrap the input inside the <label> tag.

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">

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 read by screen readers.
  • This is especially important for radios, checkboxes, and grouped choices.

Live HTML Example

Preferred Contact Method
Select Your Interests

Use aria-describedby for Validation and Help Text

Why it matters:

  • Screen readers can announce extra context tied to an input field using aria-describedby.
  • This is useful for help text, requirements, and validation errors.
  • The input points to a visible description element by id.

Correct Example (Descriptive Help Text)

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

Correct Example (Validation Message)

<label for="email">Email</label>
<input type="email" id="email" aria-describedby="email-error">

<div id="email-error" class="field-msg msg-error" role="alert">
  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 many users.
  • WCAG AA requires at least 4.5:1 for normal text and 3:1 for large text.
  • WCAG AAA requires 7:1 for normal text and 4.5:1 for large text.

How to Check Contrast:

  • Use tools like WebAIM Contrast Checker, axe DevTools, Lighthouse, or WAVE.
  • Text should be legible in all states: default, hover, focus, active, and visited.
  • Check buttons, links, placeholder text, and text on images or surfaces.

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

Use existing Web Guide tokens whenever possible, such as --color-uvu-green, --color-dark-grey, and any theme token overrides already defined in the system.

:root {
  --link: var(--color-uvu-green);
  --link-hover: var(--color-wolverine-green);
  --text-1: var(--color-dark-grey);
  --surface-1: var(--color-white);
}

Live HTML Example

This paragraph passes AA.

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.
  • Meaning should not be conveyed through color alone.
  • Accessible alerts should also include icons, text labels, shapes, or borders.

Accessibility Tip

  • Combine color with another cue such as text, icon, underline, or border.
  • Use ARIA roles like role="alert" or role="status" when appropriate.

6. ARIA and Screen Readers

Use ARIA Roles 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 do not 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 replace native HTML when native HTML already does the job.
  • ARIA adds power, but misusing it can confuse screen readers.

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 or hidden.
  • They provide state information that is otherwise invisible to assistive technologies.
  • Without these attributes, dynamic interactions 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.

Correct Example: Collapsible Section

<button aria-expanded="false" aria-controls="more-info" type="button">
  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: 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 whenever the open or closed state changes.
  • Use aria-live sparingly and intentionally.
  • Do not rely on aria-hidden alone to manage visible state.

7. Responsive and Scalable Design

Use Flexible Units: em, rem, %, and clamp()

Why it matters:

  • Fixed pixel values do not scale well for users with zoom or custom text sizing.
  • Relative units like rem and em respect user settings.
  • Flexible units support responsive layouts across devices and accessibility settings.

Common Flexible Units

  • rem: scales from the root font size.
  • em: relative to the parent font size.
  • %: useful for fluid widths and spacing.
  • clamp(): dynamic scaling between a minimum and maximum.

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-md {
  width: 100%;
  margin: 0 auto;
}

Example Using clamp() for Font Responsiveness

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

Accessibility Tip

  • Prefer font-size: 100% on the root when possible.
  • Use rem for global sizing and em for component-level adjustments.

Allow Zoom Up to 200% Without Content Loss

Why it matters:

  • WCAG requires that content remains usable up to 200% zoom without loss of content or functionality.
  • Layouts should reflow and stack properly at increased zoom.
  • Avoid fixed widths and heights that block reflow.

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 at 200% zoom to verify reflow and usability.
  • Ensure text never clips, overlaps, or disappears.

Avoid Fixed Pixel Dimensions for Critical Text and Containers

Why it matters:

  • Fixed dimensions can cause overflow or cutoff content when users zoom.
  • Critical content should expand naturally within its container.

Problem with Fixed Widths

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

Recommended Responsive Approach

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

Accessibility Tip

  • Prefer max-width and natural height.
  • Avoid fixed height unless necessary.

8. Motion & Animation

Respect prefers-reduced-motion User Preferences

Why it matters:

  • Animations and transitions can trigger discomfort for users with motion sensitivity.
  • Use prefers-reduced-motion to reduce or remove non-essential motion.

Basic CSS Example

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

Optional Example

@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 reduced-motion settings enabled.
  • Avoid autoplay motion that cannot be paused or disabled.

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 or hard of hearing.
  • They also improve comprehension for non-native speakers and users in noisy environments.
  • WCAG requires synchronized captions for video with audio and transcripts for audio-only content.

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>

<section aria-label="Transcript">
  <h3>Transcript</h3>
  <p>[Host]: Welcome to the podcast...</p>
  <p>[Guest]: Thanks for having me...</p>
</section>

Live HTML Example

Video with Captions:

DESIGN NOTE: Add a video sample and captions file for a real demo.

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

  • Provide accurate, complete captions that stay synchronized with audio.
  • Place transcripts near the media so users can find them easily.
  • Label caption tracks clearly using srclang and label.

Use Audio Descriptions for Visual Information

Why it matters:

  • Blind and low-vision users rely on descriptions to understand important visual content in video.
  • Dialogue alone may not describe key actions, facial expressions, or on-screen text.
  • WCAG requires audio descriptions when visuals are essential to understanding the content.

Correct Example (Separate Descriptive 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: Provide a Described Version

<a href="video-described.mp4">Watch described video version</a>

Example Transcript with Visual Descriptions

Transcript (with Visual Descriptions)

[Narrator]: A student walks into a sunlit library holding a stack of books.

[Host]: Welcome to our digital literacy program.

Accessibility Tip

  • If you cannot provide audio descriptions, include a transcript that describes key visuals.
  • Clearly label described versions so users can choose the accessible option.

Use <header>, <nav>, <section>, and <footer> Landmarks

Why it matters:

  • Landmark elements let assistive technology users jump to key areas of a page.
  • They define page structure semantically without needing extra ARIA in many cases.
  • They help users scan the layout of a long page.

Common Landmark Elements

  • <header> - Top section of the page or a section.
  • <nav> - A region containing navigation links.
  • <aside> - Supplementary content.
  • <footer> - Footer for the page or a section.

Correct Example

<header>
  <h1>Site Title</h1>
  <nav>...</nav>
</header>

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

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

Accessibility Tip

  • Use landmark elements appropriately and consistently.
  • Make sure landmark content has a clear heading structure inside it.

11. Testing & Auditing

Conduct a Keyboard-Only Test

Why it matters:

  • A keyboard-only test ensures navigation, forms, modals, and menus work without a mouse.
  • It is one of the fastest ways to catch major accessibility barriers.

How to Perform a Keyboard Test

  1. Avoid using the mouse or trackpad.
  2. Use Tab and Shift + Tab to move through interactive elements.
  3. Use Enter or Space to activate controls.
  4. Use arrow keys where applicable, such as menus, sliders, or radios.

Live Test Area

Focusable Link

Test with Screen Readers

Why it matters:

  • Screen readers interpret HTML and ARIA for users who are blind or low vision.
  • Testing ensures content is announced clearly and in the correct order.
  • Different screen readers and browsers can behave differently.

Popular Screen Readers

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

Use Accessibility Tools: axe DevTools, Lighthouse, WAVE

Why it matters:

  • Automated tools can quickly identify many common accessibility issues.
  • They complement manual keyboard and screen reader testing.

Popular Tools

  • axe DevTools
  • Lighthouse
  • WAVE
  • Siteimprove Accessibility Checker
  • Silktide Accessibility Checker

Example: Running Lighthouse

1. Open Chrome DevTools
2. Go to the Lighthouse tab
3. Select "Accessibility" and click "Analyze page load"
4. Review and address the issues shown

Accessibility Tip

  • Automated tools catch only part of accessibility issues.
  • Always pair automated results with manual testing.
Dark Mode - needs work

It seems that you have reduce motion enabled!