16 Checks · Code Examples · Free

Accessibility & WCAG Checklist

Accessible websites reach more users and rank better. Many accessibility best practices overlap with SEO: semantic HTML, alt text, and clear structure.

Why Accessibility Matters

Accessible websites reach more users and rank better in search engines. Many accessibility best practices overlap with SEO best practices: semantic HTML, alt text, keyboard navigation, and clear content structure all help both users and search engines.

1.3B people live with significant disability (WHO)
96% of homepages have WCAG failures (WebAIM)
4,600+ US accessibility lawsuits in 2023

The 16 Checks

Every check ranked by impact. Start at the top and work down.

# Check Category Impact Difficulty
1Use semantic HTML elementsHTMLCriticalEasy
2Add alt text to all imagesImagesCriticalEasy
3Ensure keyboard navigation worksNavigationCriticalMedium
4Maintain color contrast ratio 4.5:1DesignCriticalEasy
5Add ARIA labels to interactive elementsARIAHighEasy
6Use proper heading hierarchyStructureHighEasy
7Add skip navigation linkNavigationHighEasy
8Label all form inputsFormsHighEasy
9Provide video captionsMediaHighMedium
10Use descriptive link textLinksMediumEasy
11Avoid auto-playing mediaUXMediumEasy
12Add focus indicatorsDesignMediumEasy
13Use lang attribute on htmlHTMLMediumEasy
14Provide text alternatives for iconsDesignLowEasy
15Test with screen readerTestingLowMedium
16Run Lighthouse accessibility auditTestingLowEasy

Deep Dive: Every Check Explained

Detailed implementation guides with code examples for all 16 checks.

1 Use Semantic HTML Elements

Semantic elements like <nav>, <main>, <article>, <aside>, <header>, and <footer> convey meaning to assistive technologies. Screen readers use these landmarks to let users jump between page sections. Search engines also use them to understand content hierarchy.

# Bad: div soup with no meaning
<div class="header">...</div>
<div class="nav">...</div>
<div class="main">
  <div class="article">...</div>
</div>

# Good: semantic landmarks
<header>...</header>
<nav aria-label="Main">...</nav>
<main>
  <article>...</article>
</main>

# WCAG criteria: 1.3.1 Info and Relationships (A), 2.4.1 Bypass Blocks (A)

2 Add Alt Text to All Images

Alt text serves two purposes: it describes the image for screen reader users and provides text context for search engines when images fail to load. Every <img> must have an alt attribute. Decorative images should use alt="" (empty alt) so screen readers skip them.

# Informative image: describe the content
<img src="team-meeting.jpg"
     alt="Marketing team reviewing Q3 campaign results on a whiteboard">

# Functional image (link/button): describe the action
<a href="/">
  <img src="logo.svg" alt="Clienvora homepage">
</a>

# Decorative image: empty alt
<img src="decorative-swirl.svg" alt="">

# Complex image: use long description
<img src="org-chart.png" alt="Company org chart"
     aria-describedby="chart-desc">
<div id="chart-desc">CEO reports to board of directors. Three VPs report to CEO...</div>

# Bad alt text examples:
alt="image"           # too vague
alt="photo.jpg"       # filename is not a description
alt="click here"      # describes action, not image

# WCAG criteria: 1.1.1 Non-text Content (A)

3 Ensure Keyboard Navigation Works

Every interactive element must be reachable and operable via keyboard alone. Users who cannot use a mouse rely on Tab, Shift+Tab, Enter, Space, and arrow keys. Test by unplugging your mouse and tabbing through every page.

# Tab order: elements receive focus in logical reading order
# Focus indicator: must be visible (never outline: none without replacement)

# Custom focus styles:
:focus-visible {
  outline: 3px solid #C9A227;
  outline-offset: 2px;
}

# Make custom elements focusable:
<div role="button" tabindex="0"
     onkeydown="if(event.key==='Enter'||event.key===' ')doAction()">
  Click me
</div>

# Avoid positive tabindex values (breaks natural order):
tabindex="0"   # follows DOM order (correct)
tabindex="-1"  # programmatically focusable only
tabindex="1"   # NEVER use positive values

# Common keyboard traps to avoid:
- Modal dialogs that don't return focus on close
- Dropdown menus that trap Tab key
- Embedded iframes without keyboard access

# WCAG criteria: 2.1.1 Keyboard (A), 2.4.7 Focus Visible (AA)

4 Maintain Color Contrast Ratio 4.5:1

Text must have sufficient contrast against its background. WCAG AA requires 4.5:1 for normal text and 3:1 for large text (18pt+ or 14pt+ bold). Non-text elements like icons, borders, and focus indicators also need 3:1 contrast.

# Minimum contrast ratios (WCAG 2.1 AA):
Normal text (<18pt):     4.5:1
Large text (≥18pt):       3:1
Large bold text (≥14pt):  3:1
UI components/borders:    3:1

# How to check contrast:
1. Chrome DevTools: inspect element → color picker shows ratio
2. WebAIM Contrast Checker: webaim.org/resources/contrastchecker
3. axe DevTools: highlights contrast failures automatically

# Common failures:
- Light gray text on white (#999 on #FFF = 2.85:1 FAIL)
- Placeholder text in form fields
- Text over images without overlay
- Link text indistinguishable from body text

# WCAG criteria: 1.4.3 Contrast Minimum (AA), 1.4.6 Contrast Enhanced (AAA), 1.4.11 Non-text Contrast (AA)

5 Add ARIA Labels to Interactive Elements

ARIA attributes provide accessible names and descriptions when HTML alone cannot. The first rule of ARIA: do not use ARIA if a native HTML element already provides the semantics. Always prefer <button> over <div role="button">.

# aria-label: provides accessible name when no visible text
<button aria-label="Close dialog">
  <svg>...X icon...</svg>
</button>

# aria-labelledby: references visible text elsewhere on page
<h2 id="checkout-title">Shipping Address</h2>
<form aria-labelledby="checkout-title">...</form>

# aria-describedby: adds supplementary description
<input type="password" aria-describedby="pw-hint">
<span id="pw-hint">Must be 8+ characters with one number</span>

# aria-expanded: indicates collapsible state
<button aria-expanded="false" aria-controls="menu1">
  Menu
</button>
<ul id="menu1" hidden>...</ul>

# aria-hidden: removes element from accessibility tree
<span aria-hidden="true">★</span> <!-- decorative star -->

# aria-live: announces dynamic content changes
<div aria-live="polite">3 items in cart</div>

# WCAG criteria: 4.1.2 Name, Role, Value (A), 1.3.1 Info and Relationships (A)

6 Use Proper Heading Hierarchy

Headings create an outline that screen readers use for navigation. Never skip heading levels (e.g., h2 to h4). Every page should have exactly one <h1>. Use headings for structure, not for styling.

# Correct heading hierarchy:
<h1>Page Title</h1>
  <h2>Section One</h2>
    <h3>Subsection</h3>
    <h3>Subsection</h3>
  <h2>Section Two</h2>
    <h3>Subsection</h3>

# Bad: skipping levels for visual styling
<h1>Title</h1>
<h4>Looks smaller</h4>  <!-- WRONG: skipped h2 and h3 -->

# WCAG criteria: 1.3.1 Info and Relationships (A), 2.4.6 Headings and Labels (AA)

7 Add Skip Navigation Link

A skip link lets keyboard users bypass repetitive navigation and jump directly to the main content. It should be the first focusable element on the page and become visible on focus.

# HTML:
<a href="#main-content" class="skip-link">Skip to main content</a>
<nav>...</nav>
<main id="main-content">...</main>

# CSS:
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #C9A227;
  color: #0F172A;
  padding: 8px 16px;
  z-index: 100;
  font-weight: 600;
  transition: top 0.2s;
}
.skip-link:focus {
  top: 0;
}

# WCAG criteria: 2.4.1 Bypass Blocks (A)

8 Label All Form Inputs

Every form input needs a visible label associated with it using the for attribute or by wrapping the input in a <label> element. Placeholder text is not a substitute for labels it disappears when users type.

# Correct: explicit label with for/id
<label for="email">Email address</label>
<input type="email" id="email" name="email">

# Correct: implicit label (wrapping)
<label>
  Email address
  <input type="email" name="email">
</label>

# Error messages: link to input with aria-describedby
<label for="phone">Phone number</label>
<input type="tel" id="phone" aria-describedby="phone-error"
       aria-invalid="true">
<span id="phone-error" role="alert">
  Please enter a valid phone number
</span>

# Grouped inputs: use fieldset and legend
<fieldset>
  <legend>Shipping method</legend>
  <label><input type="radio" name="ship" value="std"> Standard</label>
  <label><input type="radio" name="ship" value="exp"> Express</label>
</fieldset>

# WCAG criteria: 1.3.1 Info and Relationships (A), 3.3.2 Labels or Instructions (A), 3.3.1 Error Identification (A)

9 Provide Video Captions

All video content with audio must have synchronized captions. Captions benefit deaf and hard-of-hearing users, non-native speakers, and users in sound-off environments. Use WebVTT format for HTML5 video.

10 Use Descriptive Link Text

Link text must make sense out of context. Screen readers often list all links on a page, so "click here" or "read more" are meaningless. Instead, describe the destination.

# Bad:
<a href="/pricing">Click here</a>
<a href="/blog/post">Read more</a>

# Good:
<a href="/pricing">View our pricing plans</a>
<a href="/blog/post">Read the full accessibility guide</a>

# WCAG criteria: 2.4.4 Link Purpose in Context (A)

11 Avoid Auto-Playing Media

Auto-playing audio or video can disorient screen reader users and make it difficult to navigate. If media must auto-play, provide a mechanism to pause or stop it within the first 3 seconds.

12 Add Focus Indicators

Focus indicators show keyboard users which element is currently active. Never remove them with outline: none without providing an alternative. Custom focus styles should be at least as visible as browser defaults.

# Never do this:
*:focus { outline: none; }  <!-- removes all focus indicators -->

# Custom focus style:
:focus-visible {
  outline: 3px solid #C9A227;
  outline-offset: 2px;
  border-radius: 4px;
}

# WCAG criteria: 2.4.7 Focus Visible (AA)

13 Use lang Attribute on HTML

The lang attribute tells screen readers which language to use for pronunciation. It also helps search engines determine the language of your content.

# Primary language:
<html lang="en">

# Mixed language content:
<p>The French word <span lang="fr">bonjour</span> means hello.</p>

# WCAG criteria: 3.1.1 Language of Page (A), 3.1.2 Language of Parts (AA)

14 Provide Text Alternatives for Icons

Icon-only buttons and links must have accessible text. Use aria-label on the element or visually hidden text inside it.

# aria-label approach:
<button aria-label="Search">
  <svg>...magnifying glass...</svg>
</button>

# Visually hidden text:
<button>
  <svg aria-hidden="true">...icon...</svg>
  <span class="sr-only">Search</span>
</button>

# CSS for sr-only:
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

15 Test with Screen Readers

Automated tools catch only 30-40% of accessibility issues. Manual screen reader testing is essential. Test with at least two screen readers across different platforms.

# Recommended screen readers:

NVDA (Windows, free)
  - Download: nvaccess.org
  - Works with Firefox and Chrome
  - Toggle: NVDA + Space to enter focus mode

JAWS (Windows, paid — 40-min demo mode)
  - Industry standard for enterprise
  - Best IE/Edge support
  - Virtual cursor: arrow keys to read

VoiceOver (Mac/iOS, built-in)
  - Cmd + F5 to toggle on Mac
  - Navigate: VO + arrow keys (VO = Ctrl + Option)
  - Rotor: VO + U for page landmarks

TalkBack (Android, built-in)
  - Settings → Accessibility → TalkBack
  - Swipe right/left to navigate
  - Double-tap to activate

# What to test:
- Can you reach every interactive element with Tab?
- Do images have meaningful alt text?
- Are form labels announced correctly?
- Do error messages get announced?
- Can you navigate by headings (NVDA: H key)?
- Does the page make sense when read linearly?

16 Run Lighthouse Accessibility Audit

Lighthouse provides an automated accessibility score and identifies common issues. It is a starting point, not a complete audit. Pair it with axe DevTools for deeper analysis and manual testing.

WCAG 2.1 Success Criteria Mapping

How each check maps to official WCAG 2.1 success criteria.

Check → WCAG Criteria

Semantic HTML 1.3.1 (A) · 2.4.1 (A)
Alt text on images 1.1.1 Non-text Content (A)
Keyboard navigation 2.1.1 Keyboard (A) · 2.4.7 Focus Visible (AA)
Color contrast 4.5:1 1.4.3 Contrast (AA) · 1.4.11 Non-text Contrast (AA)
ARIA labels 4.1.2 Name, Role, Value (A)
Heading hierarchy 1.3.1 (A) · 2.4.6 Headings (AA)
Skip navigation 2.4.1 Bypass Blocks (A)
Form labels 3.3.2 Labels (A) · 3.3.1 Error ID (A)
Video captions 1.2.2 Captions (A)
Link text 2.4.4 Link Purpose (A)
No auto-play 1.4.2 Audio Control (A)
Focus indicators 2.4.7 Focus Visible (AA)
lang attribute 3.1.1 Language of Page (A) · 3.1.2 Language of Parts (AA)

Accessibility Testing Tools

Free and built-in tools to audit and validate your accessibility implementation.

WAVE

Browser extension that overlays accessibility errors and warnings directly on your pages. Shows contrast issues, missing alt text, ARIA errors, and structural problems visually.

Free

axe DevTools

Browser extension by Deque Systems. Identifies WCAG violations with clear remediation guidance. Integrates into Chrome DevTools. The most accurate automated testing engine available.

Free

Lighthouse

Built into Chrome DevTools (Audits tab). Runs an automated accessibility audit and provides a score from 0-100. Good starting point but catches only ~30% of issues.

Free

Contrast Checker by WebAIM

Enter foreground and background colors to check WCAG AA and AAA contrast ratios. Also includes a color blindness simulator and link contrast analyzer.

Free

NVDA Screen Reader

Free, open-source screen reader for Windows. The most widely used screen reader for testing. Download from nvaccess.org. Works with Firefox and Chrome.

Free

VoiceOver

Built-in screen reader on macOS, iOS, and iPadOS. No installation needed. Toggle with Cmd+F5 on Mac. Test on iPhone with Settings → Accessibility → VoiceOver.

Built-in on Mac

Related Checklists

Keep exploring the on-page SEO series. Every checklist follows the same structure.

Image SEO Optimization

Alt text, image formats, lazy loading, and image schema markup.

Headings & Structure

Heading hierarchy, content outlines, and semantic structure for SEO.

User Experience

Core Web Vitals, mobile UX, and usability best practices.

Structured Data & Schema.org

JSON-LD implementation, schema types, and rich results.

HTML Document Structure

Proper HTML semantics, document outline, and structural elements.

Technical SEO: Accessibility

Technical accessibility audit from an SEO perspective.

Need Better Rankings

Let's Optimize Pages That Rank and Convert

Got pages stuck on page two? Traffic that won't convert? Let's fix it with a personalized on-page SEO audit.

Get a Free SEO Audit

Frequently Asked Questions

Common questions about web accessibility and SEO.

Does accessibility affect SEO?

Yes. Semantic HTML, alt text, proper heading hierarchy, and clear content structure are both accessibility requirements and SEO best practices. Google uses the same signals to understand page structure that screen readers use to navigate content. Sites with strong accessibility tend to have lower bounce rates, longer session durations, and better crawl efficiency — all of which correlate with higher rankings.

What is WCAG?

Web Content Accessibility Guidelines (WCAG) are international standards published by the W3C. WCAG 2.1 Level AA is the most commonly referenced standard for legal compliance under the ADA (US), EAA (EU), and AODA (Canada). WCAG is organized around four principles: Perceivable, Operable, Understandable, and Robust (POUR). Each principle contains success criteria at three conformance levels: A (minimum), AA (standard), and AAA (enhanced).

How do I test accessibility?

Use a combination of automated and manual testing. Run Lighthouse accessibility audit and axe DevTools for automated checks. Use WAVE to visualize issues on-page. Test keyboard navigation by tabbing through every interactive element. Test with screen readers: NVDA (free, Windows), JAWS (paid, Windows), and VoiceOver (built-in on Mac/iOS). Use WebAIM Contrast Checker for color contrast validation. Automated tools catch roughly 30-40% of accessibility issues — manual testing catches the rest.

Is accessibility legally required?

In many countries, yes. In the US, the ADA has been interpreted by courts to apply to websites. The European Accessibility Act (EAA) requires digital products and services to be accessible by June 2025. Canada's AODA and the UK Equality Act have similar requirements. Non-compliance can result in lawsuits, fines, and reputational damage. In 2023 alone, over 4,600 accessibility lawsuits were filed in the US.

What are ARIA attributes and when should I use them?

ARIA (Accessible Rich Internet Applications) attributes supplement HTML semantics when native elements cannot convey the role, state, or properties of a component. Use ARIA when there is no native HTML element that provides the needed semantics. The first rule of ARIA is: do not use ARIA if a native HTML element or attribute already exists. For example, use a <button> element instead of adding role="button" to a div.

What is the minimum color contrast ratio for WCAG AA?

WCAG 2.1 Level AA requires a contrast ratio of at least 4.5:1 for normal text (under 18pt or 14pt bold) and 3:1 for large text (18pt or 14pt bold and above). Non-text elements like icons, borders, and form fields also require a 3:1 contrast ratio against adjacent colors. Use the WebAIM Contrast Checker or Chrome DevTools to verify contrast ratios.

AA

Amir Ali

Founder of Clienvora, a content marketing agency that combines SEO and copywriting to drive rankings, traffic, and revenue. This checklist is maintained and updated regularly.