Rules reference
All 69 checks A11yMate runs. Each one maps to a WCAG 2.2 success criterion and says why it matters and how to fix it. 53 are automated, and the rest say plainly that a person needs to decide.
Showing 69 of 69 rules
No rules match. Try fewer filters or a different word.
-
Image has no alt attribute
Screen reader users hear the file name or nothing at all, so they miss whatever the picture was telling everyone else. Search engines miss it too.
How to fix it
Add an alt attribute. Describe what the image shows or says, in a short sentence. If the image is purely decorative, use an empty alt (alt="") so screen readers skip it.
<!-- Before --> <img src="team.jpg"> <!-- After: informative --> <img src="team.jpg" alt="The four of us outside the studio, laughing at a whiteboard"> <!-- After: decorative --> <img src="swirl.svg" alt=""> -
Alt text looks like a file name
Alt text such as "IMG_4032.jpg" tells a screen reader user nothing about the picture. It is read out letter by letter, which is worse than silence.
How to fix it
Replace it with a short description of what the image shows. If it is decorative, use an empty alt instead.
<!-- Before --> <img src="p.jpg" alt="IMG_4032.jpg"> <!-- After --> <img src="p.jpg" alt="A baker dusting flour over a tray of loaves"> -
Alt text starts with "image of" or similar
Screen readers already announce "image" or "graphic" before the alt text, so saying it again makes people hear "image, image of a dog".
How to fix it
Drop the opening "image of", "picture of" or "photo of" and describe the content directly.
<!-- Before --> <img src="dog.jpg" alt="Image of a dog on a beach"> <!-- After --> <img src="dog.jpg" alt="A spaniel shaking off water on a beach"> -
Alt text is very long
Alt text over about 150 characters is tiring to listen to and cannot be skipped part-way through. Long descriptions belong in the page itself.
How to fix it
Keep the alt text to the point. Put any longer explanation (for a chart or infographic, say) in visible text next to the image and refer to it.
<!-- Before --> <img src="chart.png" alt="A bar chart showing sales by month ... (200 more words)"> <!-- After --> <figure> <img src="chart.png" alt="Sales by month, rising from March to a peak in November"> <figcaption>Full figures are in the table below.</figcaption> </figure> -
Linked image has no accessible name
When an image is the only content of a link and has no alt text, a screen reader announces just "link" or reads out the web address. Nobody knows where it goes.
How to fix it
Give the image alt text that says where the link goes, not what the picture looks like.
<!-- Before --> <a href="/shop/"><img src="basket.svg"></a> <!-- After --> <a href="/shop/"><img src="basket.svg" alt="Visit the shop"></a> -
SVG marked as an image has no name
An SVG with role="img" is announced as an image. Without a name, people hear "image" and nothing else.
How to fix it
Add an aria-label, or a <title> inside the SVG referenced by aria-labelledby. If it is decorative, use aria-hidden="true" and drop the role.
<!-- Before --> <svg role="img" viewBox="0 0 24 24">...</svg> <!-- After --> <svg role="img" aria-label="Warning" viewBox="0 0 24 24">...</svg> -
Image button has no alt text
An <input type="image"> is a button made from a picture. Without alt text a screen reader cannot say what the button does.
How to fix it
Add an alt attribute that names the action, such as "Search" or "Send message".
<!-- Before --> <input type="image" src="go.png"> <!-- After --> <input type="image" src="go.png" alt="Search"> -
Image map area has no alt text
Each clickable region in an image map is a link. Without alt text, keyboard and screen reader users cannot tell the regions apart.
How to fix it
Add alt text to every <area> that has an href, describing where it goes.
<!-- Before --> <area shape="rect" coords="0,0,80,40" href="/north/"> <!-- After --> <area shape="rect" coords="0,0,80,40" href="/north/" alt="North office"> -
Page has no language set
Screen readers choose a voice and pronunciation from the page language. Without it, an English page can be read with the wrong accent, or garbled.
How to fix it
Set the lang attribute on the <html> element. WordPress does this from the Site Language setting, so check the theme is calling language_attributes().
<!-- Before --> <html> <!-- After --> <html lang="en-GB"> -
Page language code is not valid
A language code that does not exist is ignored, so assistive technology falls back to guessing.
How to fix it
Use a valid BCP 47 code such as en, en-GB or fr-CA.
<!-- Before --> <html lang="english"> <!-- After --> <html lang="en-GB"> -
Page has no title
The page title is the first thing a screen reader announces and the label on every browser tab. Without one people cannot tell pages apart.
How to fix it
Add a <title> that describes this page. WordPress themes should declare title-tag support so core writes it for you.
<!-- Before --> <title></title> <!-- After --> <title>Contact us - Acme Bakery</title> -
Several pages share the same title
If many pages have an identical title, people using tabs, history or a screen reader cannot tell where they are.
How to fix it
Make each title say what is unique about the page, with the site name last.
<!-- Before --> <title>Acme Bakery</title> <!-- on every page --> <!-- After --> <title>Sourdough classes - Acme Bakery</title> -
Page has no main heading (h1)
The h1 tells everyone what the page is about, and screen reader users often jump straight to it.
How to fix it
Add one h1 that names the page. Usually this is the post or page title.
<!-- Before --> <div class="big-title">Opening times</div> <!-- After --> <h1>Opening times</h1> -
Heading levels are skipped
Headings are a table of contents for people who navigate by them. Jumping from h2 to h4 suggests something is missing, and makes the outline confusing.
How to fix it
Use heading levels in order, without gaps. Choose the level for the structure, then style it with CSS to get the size you want.
<!-- Before --> <h2>Services</h2> <h4>Web design</h4> <!-- After --> <h2>Services</h2> <h3>Web design</h3> -
Heading is empty
An empty heading is announced as "heading" with nothing after it, and shows up as a blank entry in the heading list.
How to fix it
Add text, or remove the heading. If it was only there for spacing, use CSS margin instead.
<!-- Before --> <h3></h3> <!-- After --> <h3>Opening times</h3> -
Page has no main landmark
The main landmark lets keyboard and screen reader users jump straight past the header and menu to the content.
How to fix it
Wrap the page's primary content in a single <main> element.
<!-- After --> <header>...</header> <main id="content"> ...page content... </main> <footer>...</footer> -
No skip link
Keyboard users have to tab through the whole header and menu on every page before they reach the content. A skip link removes that effort.
How to fix it
Add a link as the first focusable thing on the page that jumps to the main content. It can be hidden until it gets focus. The Safe Fixes module can add one for you.
<a class="skip-link" href="#content">Skip to content</a> ... <main id="content"> -
List item is outside a list
A <li> that is not inside a <ul> or <ol> is not announced as part of a list, so the grouping is lost.
How to fix it
Wrap list items in <ul> or <ol>. If you only want the look, use a different element.
<!-- Before --> <li>Tea</li><li>Coffee</li> <!-- After --> <ul><li>Tea</li><li>Coffee</li></ul> -
Data table has no header cells
Screen readers announce the column and row heading as you move around a table. Without header cells, every number is read out with no context.
How to fix it
Mark the header cells with <th>, and add scope="col" or scope="row". Use tables for data only, not layout.
<table> <tr><th scope="col">Plan</th><th scope="col">Price</th></tr> <tr><td>Pro</td><td>£59</td></tr> </table> -
Frame has no title
Screen readers list frames by title. An untitled embed is announced as just "frame", so people cannot tell a map from an advert.
How to fix it
Add a title attribute that says what the embed is.
<iframe src="https://www.youtube.com/embed/abc" title="Video: how we bake sourdough"></iframe> -
Pinch zoom is switched off
Setting user-scalable=no or a low maximum-scale stops people with low vision from zooming in on a phone.
How to fix it
Remove user-scalable=no and maximum-scale from the viewport meta tag. The Safe Fixes module can do this for you.
<!-- Before --> <meta name="viewport" content="width=device-width, user-scalable=no"> <!-- After --> <meta name="viewport" content="width=device-width, initial-scale=1"> -
Page refreshes or redirects on a timer
A timed refresh can move people away before they have finished reading, which is especially hard for screen reader and switch users.
How to fix it
Remove the meta refresh. Use a server-side redirect, or let the user choose when to move on.
<!-- Remove --> <meta http-equiv="refresh" content="5; url=/next/"> -
Label points at an element that does not exist
aria-labelledby, aria-describedby and for can only work if the id they mention exists. A broken reference silently leaves the control without a name.
How to fix it
Fix the id so it matches an element on the page, or remove the attribute.
<!-- Before --> <input aria-labelledby="nme"> <label id="name-label">Name</label> <!-- After --> <input aria-labelledby="name-label"> <label id="name-label">Name</label> -
Duplicate id is used by a label or ARIA attribute
Browsers pick the first element with a given id, so a label or aria-describedby can end up attached to the wrong thing. (WCAG 2.2 dropped the old parsing rule, so duplicates only matter when something refers to them.)
How to fix it
Make every id that is referenced unique on the page.
<!-- Before --> <input id="email"> ... <input id="email"> <!-- After --> <input id="header-email"> ... <input id="footer-email"> -
Link has no text
A link with no readable content is announced as "link" and nothing else, or as its web address. People cannot tell where it goes.
How to fix it
Add visible text, or an aria-label that says where it goes. Icon-only links need a name too.
<!-- Before --> <a href="https://x.com/acme"><i class="icon-x"></i></a> <!-- After --> <a href="https://x.com/acme" aria-label="Acme on X"><i class="icon-x" aria-hidden="true"></i></a> -
Button has no name
A button without a name is announced as just "button". Screen reader and voice control users cannot find or use it.
How to fix it
Add visible text, or an aria-label for icon buttons.
<!-- Before --> <button class="menu-toggle"><svg>...</svg></button> <!-- After --> <button class="menu-toggle" aria-label="Open menu"><svg aria-hidden="true">...</svg></button> -
Link text is vague
Screen reader users often pull up a list of all links on a page. A list of ten "Read more" entries is useless.
How to fix it
Make the link say where it goes. If the design needs a short visible label, add the context for screen readers with an aria-label that starts with the visible text.
<!-- Before --> <a href="/blog/a11y/">Read more</a> <!-- After --> <a href="/blog/a11y/">Read more<span class="screen-reader-text"> about accessibility basics</span></a> -
Link opens a new tab without saying so
Opening a new window without warning can disorient people, especially if they use a screen reader or magnifier and do not notice the change.
How to fix it
Say so in the link text, or add screen reader text. Safe Fixes can add "(opens in a new tab)" automatically. Also add rel="noopener".
<a href="https://example.com" target="_blank" rel="noopener">Example <span class="screen-reader-text">(opens in a new tab)</span></a> -
Same link text goes to different places
If two links say "Details" but go to different pages, people who navigate by link list cannot tell which is which.
How to fix it
Make the text unique, or add hidden context that differs. If they genuinely go to the same place, use the same address.
<a href="/rooms/single/">Single room details</a> <a href="/rooms/double/">Double room details</a> -
Link to a file does not say what it is
People should know before they click that a link downloads a PDF or opens a spreadsheet, and roughly how large it is.
How to fix it
Include the type and size in the link text.
<a href="/brochure.pdf">Brochure (PDF, 2.4 MB)</a> -
Form field has no label
Without a label, a screen reader says "edit text" and the person has to guess what to type. Voice control users cannot name the field. A label also makes the click target larger.
How to fix it
Connect a visible <label> to the field using for and id. If the design truly has no room for a visible label, use aria-label as a last resort.
<!-- Before --> <input type="email" name="email"> <!-- After --> <label for="email">Email address</label> <input type="email" id="email" name="email"> -
Placeholder is the only label
Placeholder text disappears as soon as you start typing, is often pale grey, and is not reliably announced. People forget what the field was for.
How to fix it
Add a real label. Keep the placeholder only for an example format, if at all.
<label for="tel">Phone number</label> <input id="tel" type="tel" placeholder="e.g. 07700 900123"> -
Personal details field has no autocomplete
Autocomplete lets browsers and assistive tools fill in names, emails and addresses. It helps people with memory, motor or cognitive difficulties.
How to fix it
Add the right autocomplete token (name, email, tel, street-address, postal-code and so on).
<input type="email" id="email" name="email" autocomplete="email"> -
Radio or checkbox group has no group label
Each radio button has its own label, but people also need the question. Without a group name a screen reader just says "Yes, radio button".
How to fix it
Wrap the group in a <fieldset> with a <legend> that holds the question.
<fieldset> <legend>How should we contact you?</legend> <label><input type="radio" name="c" value="email"> Email</label> <label><input type="radio" name="c" value="phone"> Phone</label> </fieldset> -
Required field is only marked visually
A red asterisk is invisible to a screen reader. People submit the form, hit an error and have to start again.
How to fix it
Add the required attribute (or aria-required="true") as well as the visible marker.
<label for="name">Name <span aria-hidden="true">*</span></label> <input id="name" required> -
ARIA role is not valid
An unknown role is ignored, so the element loses the meaning you meant to give it.
How to fix it
Use a role from the WAI-ARIA list, or better, use the matching native HTML element.
<!-- Before --> <div role="buton">Save</div> <!-- After --> <button type="button">Save</button> -
ARIA attribute is not valid
A misspelt or made-up aria- attribute does nothing, so the information never reaches assistive technology.
How to fix it
Check the spelling against the WAI-ARIA attribute list, or remove the attribute.
<!-- Before --> <button aria-expand="false"> <!-- After --> <button aria-expanded="false"> -
Positive tabindex changes the tab order
A tabindex above 0 pulls an element to the front of the tab order and creates a confusing jump around the page.
How to fix it
Use tabindex="0" or no tabindex, and put things in the DOM in the order you want them focused.
<!-- Before --> <input tabindex="5"> <!-- After --> <input> -
Focusable element is marked as presentational
role="presentation" or "none" strips an element's meaning, but a link or button still takes focus, and the browser ignores the role to avoid hiding it.
How to fix it
Remove the role from interactive elements.
<!-- Before --> <button role="presentation">Buy</button> <!-- After --> <button>Buy</button> -
Video has no captions
Deaf and hard-of-hearing people, and anyone watching without sound, cannot follow speech in a video without captions.
How to fix it
Add a <track kind="captions"> file. For YouTube or Vimeo embeds, turn on captions in the player settings and check them. (If the captions are burned into the video, ignore this issue.)
<video controls> <source src="intro.mp4"> <track kind="captions" src="intro.en.vtt" srclang="en" label="English" default> </video> -
Media plays automatically
Sound that starts by itself fights with screen readers and can be impossible to stop. Moving video is also distracting for people with attention or vestibular difficulties.
How to fix it
Remove autoplay, or make sure the video is muted, short and has a visible pause button.
<!-- Before --> <video autoplay loop src="hero.mp4"></video> <!-- After --> <video controls muted src="hero.mp4"></video> -
Page uses marquee or blink
Scrolling or flashing text cannot be paused and is almost impossible to read for many people. The elements are also obsolete.
How to fix it
Replace with static text.
<!-- Before --> <marquee>Sale now on</marquee> <!-- After --> <p>Sale now on</p> -
Animations ignore the reduced motion setting
Some people feel ill from parallax, zooms and large movement. Their device has a "reduce motion" setting, and sites are expected to respect it.
How to fix it
Wrap non-essential animation in a prefers-reduced-motion query, or switch it off inside one. The Safe Fixes module has a toggle for this.
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } -
Content moves on its own for more than 5 seconds
Carousels, tickers and looping animations are hard to read and distracting. People need a way to pause, stop or hide them.
How to fix it
Add a visible pause control, or stop the motion after five seconds.
<button type="button" aria-pressed="false" id="pause-slider">Pause slideshow</button> -
Text does not have enough contrast
Low-contrast text is hard to read for people with low vision, in sunlight, or on a worn-out screen. AA needs 4.5:1 for normal text and 3:1 for large text (24px, or 19px bold).
How to fix it
Darken the text or lighten the background until the ratio passes. The Colour Studio suggests the nearest colour that keeps your hue.
/* Before: 2.8:1 */ color: #999999; background: #ffffff; /* After: 7:1 */ color: #595959; background: #ffffff; -
Text misses the enhanced (AAA) contrast level
AAA asks for 7:1 for normal text and 4.5:1 for large text. It is not required for AA, but it helps many people with low vision.
How to fix it
Darken the text a little further if you are aiming for AAA.
color: #3b3b3b; background: #ffffff; /* 11.6:1 */ -
Interface component or border has low contrast
Form field borders, icons and other parts you need to see to use the page need at least 3:1 against what is behind them.
How to fix it
Darken the border or icon colour to at least 3:1 against its background.
input { border: 1px solid #767676; } /* 4.5:1 on white */ -
Link is only distinguished by colour
People who cannot tell colours apart cannot see links that differ only by hue. If the link colour is the only clue, it needs 3:1 against the surrounding text.
How to fix it
Underline links in body text (Safe Fixes can do that), or make the link colour at least 3:1 against the text around it, and give it another cue on hover and focus.
p a { text-decoration: underline; } -
Text sits over an image or gradient
A tool cannot know how much contrast text has when the background is a photo or gradient. It might be fine in one spot and unreadable in another.
How to fix it
Check the text against the lightest and darkest parts it covers. Add a solid or semi-transparent overlay behind the text if in doubt.
.hero__text { background: rgb(14 17 22 / 0.7); color: #fff; } -
Text is smaller than 12px
Very small text is hard to read for everyone, and people zooming in may hit layout limits sooner.
How to fix it
Make readable text at least 12px, and body text at least 16px.
small, .meta { font-size: 0.875rem; } /* 14px */ -
Body text is smaller than 16px
16px is the usual comfortable minimum for body copy. Smaller type works for some readers but not for many.
How to fix it
Set the base font size to 1rem (16px) or more and scale up from there.
html { font-size: 100%; } body { font-size: 1rem; } -
Line spacing is tight
Tight lines are hard to track, especially for readers with dyslexia or low vision. WCAG asks that content survives line height of 1.5, and 1.5 is a good default.
How to fix it
Set body text line-height to 1.5 or more.
p { line-height: 1.6; } -
Lines of text are very long
Lines over about 80 characters make it hard to find the start of the next line. This is an AAA suggestion.
How to fix it
Limit the text column width to around 45 to 75 characters, for example with max-width: 65ch.
.entry-content { max-width: 65ch; } -
Text is justified
Justified text creates uneven gaps between words, which are hard for readers with dyslexia.
How to fix it
Use left-aligned text (or right-aligned for right-to-left languages).
p { text-align: left; } -
Long passage in capitals
Long runs of capitals are slower to read, and screen readers can spell out some acronyms or shout.
How to fix it
Use sentence case for passages, and keep capitals for short labels.
h3 { text-transform: none; } -
Long passage in italics
Long stretches of italic text are harder to read, particularly for people with dyslexia.
How to fix it
Use italics for emphasis only, not for whole paragraphs.
blockquote { font-style: normal; border-left: 4px solid currentColor; } -
Very thin text at small sizes
Hairline weights vanish on low-resolution screens and in bright light, especially at small sizes.
How to fix it
Use a weight of 300 or heavier for text below 24px.
body { font-weight: 400; } -
Tight letter spacing on body text
Negative letter spacing makes letters touch, which blurs words for many readers.
How to fix it
Remove negative letter-spacing on body text (small amounts on large headings are fine).
p { letter-spacing: normal; } -
Click target is smaller than 24 by 24 pixels
Tiny buttons and links are hard to hit with a finger, a tremor, or a mouse. WCAG 2.2 AA asks for at least 24 by 24 CSS pixels, unless there is spacing around them.
How to fix it
Increase the size or padding of the target, or leave 24px of space around it.
.icon-button { min-width: 24px; min-height: 24px; padding: 8px; } -
Click target is smaller than 44 by 44 pixels
44 by 44 is the comfortable size for touch. It is an AAA recommendation.
How to fix it
Increase padding on touch controls to reach about 44px.
.nav a { display: inline-block; min-height: 44px; padding: 12px; } -
No visible focus indicator
Keyboard users need to see where they are. If focusing a control changes nothing on screen, they are lost.
How to fix it
Never remove the outline without replacing it. Add a clear :focus-visible style. Safe Fixes can add a contrast-checked ring for you.
:focus-visible { outline: 3px solid #2A3BFF; outline-offset: 2px; } -
Focused element is hidden behind a sticky header
When a fixed header or banner covers an element as you tab to it, you cannot see what is focused.
How to fix it
Add scroll-padding-top equal to the height of the sticky element, so focused items scroll into clear view.
html { scroll-padding-top: 5rem; } -
Page scrolls sideways at 320px wide
People who zoom to 400% on a desktop get the equivalent of a 320px-wide screen. If the page scrolls in two directions, reading is a chore.
How to fix it
Find the element that is wider than the screen (often a fixed width, table, image or code block) and let it shrink or scroll on its own.
img, video, iframe { max-width: 100%; height: auto; } pre, table { overflow-x: auto; } -
Text is cut off when spacing is increased
Some people need wider letter, word and line spacing. If your layout has fixed heights, their text is clipped or overlaps.
How to fix it
Avoid fixed heights on text containers. Use min-height and let the box grow.
.card { min-height: 12rem; } /* not height */ -
Text is hard to read
Plain writing helps everyone, and is essential for many people with cognitive or learning disabilities. The Flesch reading ease score for this page is low (English only).
How to fix it
Use shorter sentences and everyday words, and explain jargon. Aim for a score of 60 or more.
<!-- Before --> <p>Utilisation of the facility is contingent upon prior authorisation.</p> <!-- After --> <p>You need to book before you use the room.</p> -
Paragraph is very long
Walls of text are daunting. Short paragraphs and clear headings make a page easier to scan and to follow.
How to fix it
Break long paragraphs into shorter ones, and add subheadings.
<p>One idea per paragraph.</p> <p>The next idea starts a new one.</p> -
Page relies on PDF documents
PDFs are often not accessible: missing tags, reading order, alt text. They are also harder to read on phones.
How to fix it
Publish the same content as a web page, and make sure any PDF you keep is tagged and tested.
<a href="/prices/">Our prices</a> (also available as a <a href="/prices.pdf">PDF</a>)