How to Fix the 10 Most Common Accessibility Issues
After analyzing 10,000+ websites with AccessAudit, we've identified the accessibility issues that appear most frequently.
The good news? Most of them take less than 5 minutes to fix.
Here's your practical guide to fixing the top 10 issues we see every day.
1. Missing Image Alt Text (Found on 87% of Sites)
The Problem
Screen readers can't describe images without alt text. Users miss important visual information.
How to Identify
<!-- Problem -->
<img src="product.jpg">
<img src="logo.png">
The Fix
<!-- Solution -->
<img src="product.jpg" alt="Blue running shoes with white laces">
<img src="logo.png" alt="AccessAudit">
<!-- For decorative images -->
<img src="divider.png" alt="">
Decision Tree for Alt Text
- Is it decorative? → Use
alt="" - Is it a link? → Describe the destination
- Is it informative? → Describe what it shows
- Is it functional? → Describe what it does
- Is it complex? → Use alt + long description
Time to Fix
⏱️ 2 minutes per image
2. Poor Color Contrast (Found on 73% of Sites)
The Problem
Low contrast makes text unreadable for users with visual impairments or in bright sunlight.
WCAG Requirements
- Normal text (< 18pt): 4.5:1 contrast ratio
- Large text (≥ 18pt): 3:1 contrast ratio
- UI components: 3:1 contrast ratio
Common Failures
/* ❌ Fails - 2.8:1 ratio */
.text { color: #999; background: #fff; }
/* ❌ Fails - 2.1:1 ratio */
.link { color: #6CB4EE; background: #fff; }
/* ❌ Fails - 1.9:1 ratio */
.button { color: #ccc; background: #fff; }
The Fix
/* ✓ Passes - 5.7:1 ratio */
.text { color: #666; background: #fff; }
/* ✓ Passes - 4.5:1 ratio */
.link { color: #0066CC; background: #fff; }
/* ✓ Passes - 4.6:1 ratio */
.button { color: #767676; background: #fff; }
Quick Tools
- Chrome DevTools (Inspect → Accessibility pane)
- AccessAudit automated scanner
- WebAIM Contrast Checker
Time to Fix
⏱️ 5 minutes to update your CSS variables
3. Missing Form Labels (Found on 59% of Sites)
The Problem
Screen readers can't announce what each field is for without proper labels.
How to Identify
<!-- ❌ Problem - Placeholder is not a label -->
<input type="email" placeholder="Email">
<!-- ❌ Problem - Visual label but not associated -->
<span>Password</span>
<input type="password">
The Fix
<!-- ✓ Solution 1: Visible label -->
<label for="email">Email Address</label>
<input type="email" id="email" placeholder="you@example.com">
<!-- ✓ Solution 2: Wrapped label -->
<label>
Password
<input type="password">
</label>
<!-- ✓ Solution 3: Visually hidden label (if design requires) -->
<label for="search" class="sr-only">Search</label>
<input type="text" id="search" placeholder="Search...">
CSS for Screen-Reader-Only Text
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
Time to Fix
⏱️ 3 minutes per form
4. Empty Links (Found on 64% of Sites)
The Problem
Links with no text content are announced as "link" with no context.
How to Identify
<!-- ❌ Problem - Icon-only links -->
<a href="/cart">
<i class="icon-cart"></i>
</a>
<!-- ❌ Problem - Image links without alt -->
<a href="/home">
<img src="logo.png">
</a>
The Fix
<!-- ✓ Solution 1: Add aria-label -->
<a href="/cart" aria-label="Shopping cart">
<i class="icon-cart" aria-hidden="true"></i>
</a>
<!-- ✓ Solution 2: Add screen reader text -->
<a href="/cart">
<i class="icon-cart" aria-hidden="true"></i>
<span class="sr-only">Shopping cart</span>
</a>
<!-- ✓ Solution 3: Use alt text on image -->
<a href="/home">
<img src="logo.png" alt="AccessAudit home">
</a>
Time to Fix
⏱️ 2 minutes per link
5. Missing Skip Navigation (Found on 91% of Sites)
The Problem
Keyboard users must tab through the entire navigation on every page.
The Fix
<!-- Add this as first element in <body> -->
<a href="#main-content" class="skip-link">
Skip to main content
</a>
<!-- ... navigation here ... -->
<main id="main-content">
<!-- Your page content -->
</main>
CSS for Skip Link
/* Only show on keyboard focus */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
text-decoration: none;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
Time to Fix
⏱️ 5 minutes once, benefits entire site
6. Missing Page Language (Found on 82% of Sites)
The Problem
Screen readers don't know which language to use for pronunciation.
How to Identify
<!-- ❌ Problem -->
<!DOCTYPE html>
<html>
<head>
The Fix
<!-- ✓ Solution -->
<!DOCTYPE html>
<html lang="en">
<head>
For multi-language sections:
<!-- Page in English, section in Spanish -->
<html lang="en">
<body>
<p>Welcome to our site.</p>
<blockquote lang="es">
Bienvenidos a nuestro sitio.
</blockquote>
</body>
</html>
Time to Fix
⏱️ 30 seconds
7. Poor Heading Structure (Found on 68% of Sites)
The Problem
Headings out of order confuse screen reader users navigating by headings.
How to Identify
<!-- ❌ Problem - Skipped levels -->
<h1>Page Title</h1>
<h3>Section Title</h3> <!-- Skipped h2 -->
<h2>Subsection</h2> <!-- Out of order -->
The Fix
<!-- ✓ Solution - Logical hierarchy -->
<h1>Page Title</h1>
<h2>Main Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Another Main Section</h2>
<h3>Subsection</h3>
Rules to Follow
- One H1 per page (page title)
- Don't skip levels (h1 → h2 → h3, not h1 → h3)
- Use headings for structure, not styling
- Order matters - keep hierarchy logical
If Design Conflicts
<!-- Use aria-level for visual vs. semantic hierarchy -->
<h2 class="looks-like-h4" aria-level="2">
Semantically H2, Visually H4
</h2>
Time to Fix
⏱️ 10 minutes to audit and fix
8. No Focus Indicators (Found on 71% of Sites)
The Problem
Keyboard users can't see where they are on the page.
How to Identify
/* ❌ Problem - Focus removed */
*:focus {
outline: none;
}
button:focus,
a:focus {
outline: 0;
}
The Fix
/* ✓ Solution - Custom focus styles */
*:focus {
outline: 2px solid #0066CC;
outline-offset: 2px;
}
/* Enhanced for specific elements */
button:focus {
outline: 2px solid #0066CC;
outline-offset: 2px;
box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.2);
}
/* Visible focus, hidden when using mouse */
*:focus:not(:focus-visible) {
outline: none;
}
*:focus-visible {
outline: 2px solid #0066CC;
outline-offset: 2px;
}
Time to Fix
⏱️ 5 minutes for global styles
9. Missing ARIA Labels on Buttons (Found on 56% of Sites)
The Problem
Icon-only buttons have no accessible name.
How to Identify
<!-- ❌ Problem -->
<button><i class="icon-close"></i></button>
<button>×</button>
<button><img src="menu.svg"></button>
The Fix
<!-- ✓ Solution 1: aria-label -->
<button aria-label="Close dialog">
<i class="icon-close" aria-hidden="true"></i>
</button>
<!-- ✓ Solution 2: Screen reader text -->
<button>
<i class="icon-close" aria-hidden="true"></i>
<span class="sr-only">Close dialog</span>
</button>
<!-- ✓ Solution 3: title attribute (less preferred) -->
<button title="Close dialog">
<i class="icon-close"></i>
</button>
Time to Fix
⏱️ 2 minutes per button
10. Inaccessible Modals (Found on 63% of Sites)
The Problem
Focus isn't trapped in modals, keyboard users can't close them, or screen readers don't announce them.
The Fix
<!-- Accessible modal structure -->
<div
role="dialog"
aria-labelledby="modal-title"
aria-describedby="modal-desc"
aria-modal="true"
>
<h2 id="modal-title">Confirm Action</h2>
<p id="modal-desc">Are you sure you want to delete this item?</p>
<button onclick="confirmAction()">Confirm</button>
<button onclick="closeModal()" aria-label="Cancel and close dialog">
Cancel
</button>
</div>
JavaScript for Focus Management
function openModal(modal) {
// Store currently focused element
const previousFocus = document.activeElement
// Show modal
modal.style.display = 'block'
// Move focus to modal
modal.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])').focus()
// Trap focus
modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
trapFocus(e, modal)
}
if (e.key === 'Escape') {
closeModal(modal, previousFocus)
}
})
}
function closeModal(modal, previousFocus) {
modal.style.display = 'none'
// Return focus to trigger element
previousFocus.focus()
}
Time to Fix
⏱️ 15 minutes with focus trap logic
Quick Wins Summary
If you're short on time, prioritize these fixes:
- 5 minutes: Add page language (
<html lang="en">) - 5 minutes: Add skip navigation link
- 10 minutes: Fix form labels
- 15 minutes: Add alt text to images
- 20 minutes: Fix color contrast in CSS
Total: 55 minutes to fix the most critical issues.
How to Prevent These Issues
1. Use Automated Scanning
Run AccessAudit on every deployment to catch issues before they go live.
2. Include Accessibility in Code Reviews
Add an accessibility checklist to your PR template:
- [ ] All images have alt text
- [ ] Forms have labels
- [ ] Color contrast passes
- [ ] Keyboard navigation works
3. Test with Real Users
Nothing beats testing with actual screen reader users and keyboard-only navigation.
4. Use Linting Tools
- eslint-plugin-jsx-a11y (React)
- axe-core (any framework)
- pa11y (CI/CD integration)
Need Help?
AccessAudit automatically detects all these issues and provides fix recommendations with copy-paste code.
Found this helpful? Share it with your team and help make the web more accessible for everyone.
Tags
Ready to Make Your Website Accessible?
Scan your entire site for WCAG compliance issues in minutes.
Start Free Trial