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)
- Sign up for an account
- Complete your profile
- 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:
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 ordertabindex="-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:
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
Modal Title
This modal matches the real modal styles in wg-utilities-accessibility.css. Press Tab to cycle inside and Esc to close.
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-visibleis 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 LinkDo 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
foron the label that matches theidof 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
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)
Low Contrast (Fails WCAG)
Large Text with 3:1 Contrast (Passes AA for large text)
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"orrole="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
This content is now visible and announced to screen readers.
Accessibility Tip
- Update
aria-expandedwhenever the open or closed state changes. - Use
aria-livesparingly and intentionally. - Do not rely on
aria-hiddenalone 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
remandemrespect 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
remfor global sizing andemfor 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-widthand natural height. - Avoid fixed
heightunless 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-motionto 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
srclangandlabel.
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.
10. Navigation & Landmarks
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
- Avoid using the mouse or trackpad.
- Use Tab and Shift + Tab to move through interactive elements.
- Use Enter or Space to activate controls.
- Use arrow keys where applicable, such as menus, sliders, or radios.
Live Test Area
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.
It seems that you have reduce motion enabled!