How to fix the most common issues
Before and after code for the problems scans find most often.
These are the rules scans report most often, with a failing example and a corrected one for each. Search for
the rule name on your Issues tab (for example color-contrast) to see how many times it occurs on
your site.
color-contrast: text is hard to read
Why it matters. People with low vision, color blindness, or a phone in bright sunlight need enough difference between text and its background. WCAG 1.4.3 asks for a contrast ratio of at least 4.5 to 1 for normal text, and 3 to 1 for large text (18pt, or 14pt bold).
Fails
<p style="color: #94a3b8; background: #ffffff;">
Secondary details
</p>
Light grey on white is only 2.6 to 1.
Passes
<p style="color: #475569; background: #ffffff;">
Secondary details
</p>
Darker slate on white is 7.6 to 1.
How to fix it. Darken the text or lighten the background until it passes. Fix the color once in your theme or CSS variables rather than element by element. Check any pair with the contrast checker. Remember placeholder text, text over images, and text in hover and disabled states.
image-alt: images with no text alternative
Why it matters. A screen reader cannot describe a picture without alt text (WCAG 1.1.1).
Fails
<img src="/team.jpg">
Passes
<img src="/team.jpg"
alt="Five staff members standing outside the front office">
How to fix it. Describe what the image shows or what it does, as briefly as you can. If an
image is purely decorative, use an empty alt so screen readers skip it: alt="". If the image is
inside a link, the alt text should say where the link goes. A scan can tell that alt text is missing but cannot
judge whether your text is good, so review it yourself.
label: form fields with no label
Why it matters. Without a label, a screen reader user hears "edit text" with no clue what to type, and sighted users lose the clickable label target (WCAG 1.3.1, 3.3.2, 4.1.2).
Fails
<input type="email" placeholder="Email">
A placeholder disappears as soon as someone types and is not a reliable label.
Passes
<label for="email">Email address</label>
<input type="email" id="email" autocomplete="email">
How to fix it. Give every field a visible <label> tied to the field by
for and id. If the design truly has no room for visible text, use
aria-label as a last resort.
link-name: links with no readable name
Why it matters. A link that holds only an icon is announced as just "link" (WCAG 2.4.4, 4.1.2). People who jump through a list of links hear a row of meaningless entries.
Fails
<a href="https://example.com/cart">
<svg viewBox="0 0 24 24">...</svg>
</a>
Passes
<a href="https://example.com/cart"
aria-label="View cart">
<svg viewBox="0 0 24 24" aria-hidden="true">...</svg>
</a>
How to fix it. Add visible text, or an aria-label that says where the link goes.
Avoid "click here" and "read more" on their own. Use text that makes sense out of context, such as "Read the
pricing guide".
button-name: buttons with no name
Fails
<button class="close">
<svg viewBox="0 0 24 24">...</svg>
</button>
Passes
<button class="close" aria-label="Close dialog">
<svg viewBox="0 0 24 24" aria-hidden="true">...</svg>
</button>
How to fix it. The same idea as links (WCAG 4.1.2). Icon-only buttons such as close, menu, search and carousel arrows are the usual culprits.
html-has-lang and document-title: page basics
Why it matters. Screen readers use the page language to choose the right pronunciation (WCAG 3.1.1), and the page title is the first thing announced when a page loads (WCAG 2.4.2).
Fails
<html>
<head></head>
Passes
<html lang="en">
<head>
<title>Pricing | Example Company</title>
</head>
How to fix it. Set lang on the <html> tag and give every page a unique, descriptive <title>.
link-in-text-block: links you can only find by color
Why it matters. If a link inside a paragraph is only a different color, people who cannot tell the colors apart cannot see that it is a link (WCAG 1.4.1).
Fails
a { color: #0369a1; text-decoration: none; }
Passes
a { color: #0369a1; text-decoration: underline; }
How to fix it. Keep the underline for links in running text. Remove it only in navigation where position makes the purpose clear.
aria-required-children: ARIA roles with the wrong contents
Why it matters. Some ARIA roles only work when they contain certain child roles. A
menu with no menuitem inside it is announced as an empty menu.
Fails
<div role="menu">
<div>Profile</div>
<div>Sign out</div>
</div>
Passes
<div role="menu">
<button role="menuitem">Profile</button>
<button role="menuitem">Sign out</button>
</div>
How to fix it. Add the missing child roles. If you do not need custom widget behavior, remove the ARIA and use plain HTML such as a list of links, which needs no extra work. Use the ARIA inspector to check a snippet.
heading-order: skipped heading levels
Why it matters. Screen reader users navigate by headings. A jump from a level 2 to a level 4 suggests missing content. This is a best-practice suggestion rather than a WCAG failure.
Fails
<h2>Our services</h2>
<h4>Audits</h4>
Passes
<h2>Our services</h2>
<h3>Audits</h3>
How to fix it. Choose heading levels for structure, not size. Use CSS to change how big a heading looks.
region and landmark rules: page structure
Why it matters. Landmarks let people skip straight to the main content or the navigation. The
rules region, landmark-one-main and landmark-unique are best-practice
suggestions. Each page should have one <main>, and all visible content should sit inside a
landmark.
Fails
<body>
<div class="header">...</div>
<div class="content">...</div>
<div class="footer">...</div>
</body>
Passes
<body>
<header>...</header>
<nav aria-label="Main">...</nav>
<main>...</main>
<footer>...</footer>
</body>
If a page has two navs, give each its own aria-label.
These often come from a theme or page builder. Fixing the template once usually clears the rule across many pages.
Still stuck? Contact us with your site address and what you expected to happen.