WCAG Fix Templates
Common accessibility issues with copy-paste code solutions
Critical
Missing Alt Text on Images
Images must have alternative text that describes their content or function.
✗ Don't do this
<img src="product.jpg">
✓ Do this instead
<img src="product.jpg" alt="Blue wireless headphones with noise cancellation">
Tips:
- Describe the image content, not just "image of..."
- Use empty alt="" for decorative images
- Keep alt text under 125 characters
- For complex images, use longdesc or figure/figcaption
Critical
Empty or Non-descriptive Links
Links must have text that describes their destination or purpose.
✗ Don't do this
<a href="/products"><i class="icon-arrow"></i></a>
<a href="/more">Click here</a>
✓ Do this instead
<a href="/products">
<i class="icon-arrow" aria-hidden="true"></i>
<span class="sr-only">View all products</span>
</a>
<a href="/more">Read more about our services</a>
Tips:
- Avoid "click here", "read more", "learn more" alone
- Use aria-label for icon-only links
- Link text should make sense out of context
- Hide decorative icons with aria-hidden="true"
Critical
Missing Form Labels
Form inputs must have associated labels that describe their purpose.
✗ Don't do this
<input type="email" placeholder="Enter email">
✓ Do this instead
<label for="email">Email Address</label>
<input type="email" id="email" placeholder="Enter email">
<!-- Or with aria-label -->
<input type="email" aria-label="Email Address" placeholder="Enter email">
Tips:
- Always use <label> with matching for/id
- Placeholder is not a substitute for label
- Use aria-labelledby for complex labels
- Group related fields with fieldset/legend
Major
Insufficient Color Contrast
Text must have sufficient contrast against its background.
✗ Don't do this
.light-text {
color: #999999;
background: #ffffff;
/* Contrast ratio: 2.85:1 - FAILS */
}
✓ Do this instead
.accessible-text {
color: #595959;
background: #ffffff;
/* Contrast ratio: 7:1 - PASSES AAA */
}
.large-text {
color: #767676;
background: #ffffff;
font-size: 18pt;
/* Contrast ratio: 4.54:1 - PASSES AA */
}
Tips:
- Normal text: minimum 4.5:1 ratio (AA)
- Large text (18pt+): minimum 3:1 ratio
- Use contrast checker tools
- Consider dark mode alternatives
Major
Missing Document Language
The page must specify its primary language.
✗ Don't do this
<html>
<head>...</head>
</html>
✓ Do this instead
<html lang="en">
<head>...</head>
</html>
<!-- For multilingual content -->
<p>The French word <span lang="fr">bonjour</span> means hello.</p>
Tips:
- Use ISO 639-1 language codes (en, es, fr, zh)
- Specify regional variants: en-US, en-GB, zh-TW
- Mark language changes within content
- Helps screen readers with pronunciation
Critical
Not Keyboard Accessible
All functionality must be available via keyboard.
✗ Don't do this
<div onclick="openMenu()">Menu</div>
<span class="button" onclick="submit()">Submit</span>
✓ Do this instead
<button type="button" onclick="openMenu()">Menu</button>
<button type="submit">Submit</button>
<!-- If div is necessary -->
<div role="button" tabindex="0"
onclick="openMenu()"
onkeydown="if(event.key==='Enter')openMenu()">
Menu
</div>
Tips:
- Use native interactive elements (button, a, input)
- Add tabindex="0" for custom interactive elements
- Handle both click and keyboard events
- Ensure visible focus indicators
Major
Missing Focus Indicator
Interactive elements must have a visible focus indicator.
✗ Don't do this
:focus {
outline: none;
}
✓ Do this instead
:focus {
outline: 2px solid #1e3a5f;
outline-offset: 2px;
}
/* Custom focus styles */
:focus-visible {
outline: 2px solid #1e3a5f;
box-shadow: 0 0 0 4px rgba(30, 58, 95, 0.3);
}
/* Remove only for mouse users */
:focus:not(:focus-visible) {
outline: none;
}
Tips:
- Never use outline:none without alternative
- Focus indicator should be clearly visible
- Use :focus-visible for keyboard-only focus
- Contrast ratio of 3:1 for focus indicator
Major
Improper Heading Structure
Headings must be in logical hierarchical order.
✗ Don't do this
<h1>Page Title</h1>
<h3>Section</h3> <!-- Skipped h2 -->
<h5>Subsection</h5> <!-- Skipped h4 -->
✓ Do this instead
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Another Section</h2>
<!-- Styling without breaking hierarchy -->
<h2 class="text-xl">Styled as large</h2>
<h3 class="text-xl">Also styled as large</h3>
Tips:
- Start with one h1 per page
- Never skip heading levels
- Use CSS for visual styling, not heading levels
- Headings help screen reader navigation
Major
Incorrect ARIA Usage
ARIA attributes must be used correctly.
✗ Don't do this
<div aria-label="Menu">
<button aria-hidden="true">Open</button>
</div>
<input aria-required="yes">
✓ Do this instead
<nav aria-label="Main navigation">
<button aria-expanded="false" aria-controls="menu">
Open Menu
</button>
<ul id="menu" hidden>...</ul>
</nav>
<input aria-required="true" required>
Tips:
- First rule of ARIA: don't use ARIA if you can use HTML
- Use aria-hidden carefully - hides from screen readers
- Boolean ARIA values are "true" or "false", not "yes"
- Test with actual screen readers
Minor
Missing Skip Navigation Link
Provide a way to skip repetitive content.
✗ Don't do this
<body>
<nav>... long navigation ...</nav>
<main>Content</main>
</body>
✓ Do this instead
<body>
<a href="#main" class="skip-link">Skip to main content</a>
<nav>... long navigation ...</nav>
<main id="main" tabindex="-1">Content</main>
</body>
<style>
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #1e3a5f;
color: white;
padding: 8px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
</style>
Tips:
- Skip link should be first focusable element
- Target should have tabindex="-1" for focus
- Make visible on focus for sighted keyboard users
- Consider multiple skip links for complex pages
Find these issues automatically
WCAG Pulse scans your website and shows exactly which fixes you need.
Try Free Scan