Search topics
Status dots told apart by colour alone
An order list marks each order with a small green, amber or red dot and a key above it, so only the dot's colour says which payment failed.
.status-failed { background: #e03131; } The problem
People who can't tell red from green can't see which order's payment failed, because only the colour of a dot says so.
A shop's account page lists your orders: the order number, the date, the total and, at the end of each row, a small coloured dot. Green is Delivered, amber is On its way and red is Payment failed, and a key above the list says so. The design keeps each row short enough to fit a phone on one line, and a dot reads at a glance where a word would wrap. The developer built it with care: each dot carries visually hidden text, so a screen reader says "Payment failed" at the end of the row.
Now look at the list as someone with deuteranopia, a red–green colour vision deficiency, sees it. The green, the amber and the red turn into nearly the same olive. The key still says which colour means what, but its three dots look alike as well. Order 1044's payment has failed and the shop is waiting for another card, but the person it belongs to sees four orders that look the same, and nothing on the screen tells them which one needs them.
WCAG 1.4.1 Use of Color says colour must not be the only visual means of conveying information, and an order's status is information. The dots differ from one another in colour and in nothing else: the same size, the same round shape, the same place in the row. The key doesn't help, because it is matched to the rows by the same colours. Nor does the hidden text: the Understanding page for 1.4.1 says that information passed to assistive technology in the code can still fail the criterion, since it asks for a visible alternative to colour.
Understanding 1.4.1 allows one way for colour to carry the difference: two colours that also differ in lightness, by a contrast ratio of at least 3:1 between them, count as a second visual cue. These three are far from it. Against each other, the green #2f9e44, the amber #b7791f and the red #e03131 reach only 1.06:1 to 1.31:1, so they differ almost entirely in hue, and hue is what a colour vision deficiency takes away. No set of three status dots on a white page can meet that exception: a dot with no word beside it needs 3:1 against white under WCAG 1.4.11 Non-text Contrast, and that leaves room for two colours 3:1 apart, never three.
The same happens on a phone in sunlight or a dimmed laptop screen, where the three colours fade into one another. Screen reader users are not shut out here: the hidden text tells them each status. The failure is for people who look at the list.
3 of 10 groups affected
- No vision (not affected)
- Low vision (affected)
- Colour vision (affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Without perception of colour With a red–green colour vision deficiency, the green, amber and red dots can all look like one olive, so neither the rows nor the key say which payment failed.
- Limited vision A 10-pixel dot is a speck to people with low contrast sensitivity, and at 400% zoom the key has scrolled out of view, so each colour has to be remembered before it can be matched.
- Limited language, cognitive and learning abilities A key of colours has to be learned and held in mind while reading the rows, which is hard for people with memory or attention difficulties; a word in the row asks nothing of memory.
Nothing in the markup is wrong. Each dot is an empty span with a hidden name, and a scan that checks names passes it. axe checks colour used alone only for links in a block of text, and none of its rules compares the dots in a list. The audit can find small coloured markers that carry no visible words and come in two or more colours in one list or table, but whether the colours mean something takes a person to decide, so they go to review. When asked to fix it, AI coding tools tend to add a title or an aria-label to the dot, which adds text that nobody sees (a title shows only to a mouse resting on a 10-pixel dot), or swap in a palette sold as safe for colour blindness, which helps some people tell the hues apart and still leaves colour as the only cue.
Try it
Find the order whose payment failed.
Turn on the simulation to see the list as someone with deuteranopia, a red–green colour vision deficiency, sees it. Can you still tell which order it is?
Broken Can you fix this?
Your orders
- Delivered
- On its way
- Payment failed
- Order 1045 18 Oct $32.00 On its way
- Order 1044 15 Oct $64.00 Payment failed
- Order 1041 2 Oct $18.00 Delivered
- Order 1038 24 Sep $96.00 Delivered
The fix
Write each status as a word beside its dot, or give each status a shape of its own.
- 1Every status shown in colour is also shown in words, or by a shape of its own.
- 2Status words need 4.5:1 against their background; an icon or dot with no word beside it needs 3:1.
- 3Text only a screen reader gets is not the second cue: it has to be seen.
<h2>Your orders</h2><ul class="legend"> <li> <span class="status status-delivered"></span> Delivered </li> <li> <span class="status status-shipped"></span> On its way </li> <li> <span class="status status-failed"></span> Payment failed </li></ul><ol class="orders"> <li> <a href="/orders/1044">Order 1044</a> <span>15 Oct</span> <span>$64.00</span> <span class="status status-failed"><span class="visually-hidden">Payment failed</span></span> </li> …</ol>The status written beside the dot
<h2>Your orders</h2><ol class="orders"> <li> <a href="/orders/1044">Order 1044</a> <span>15 Oct</span> <span>$64.00</span> <span class="status status-failed">Payment failed</span> </li> …</ol>Why this fix: Say it in words, not only in the styling
A screen reader hears each status, but on screen the dots differ by colour alone, and the key above can be matched to them only by the same colour.
Each row now says its status in words, so the colour adds to the word instead of carrying it. The dot keeps the design's colour coding for everyone who can see it, the key above the list is no longer needed, and the hidden text goes, because the visible word is what a screen reader reads. The word is set in the text colour, not in the status colour: the amber has 3.64:1 against white, enough for a dot but short of the 4.5:1 that text needs. On a phone, the word wraps under the total rather than being dropped.
Both pass 1.4.1. Use the word: it needs no key, works at any zoom and for every reader, and costs only room for two words in each row, which the phone layout in the design file should show wrapping, not dropped. The shapes keep the short row, but they lean on the key. Choose them only where a word really can't fit, such as a dense table on an internal dashboard, and keep each shape's word in the key and in its hidden text.
A title on the dot is not a second cue. It shows only to a mouse that rests on the dot, never to touch or the keyboard; form field labels and hints only in a title tooltip shows the same limit on form fields. A soft pill that holds the word on a tint of the status colour works as well as a plain word, and the design ideas below show it and other looks.
Make the status a component that takes the word, not the colour: <OrderStatus status="failed"> renders both the dot and "Payment failed" from one table, so no page can draw the dot without the word. The same table can serve stock levels, payment states and booking slots, where the same dots tend to appear.
In a Windows contrast theme, the browser replaces background colours with the theme's own, so the Before's dots disappear altogether. The word in the first fix stays. The shapes in the second fix stay because they are drawn as strokes in currentColor; an icon with a fixed fill keeps its own colour, which can be lost against the theme's background. High contrast mode hiding focus, icons and selections covers that case.
Design ideas
A status can keep its colour and still be read without it.
Four more ways to draw the same two orders, in the guide’s colours. Two say which payment failed in words; two say it only with colour.
In the design file
- Write each status in words wherever it appears.
- Where a word can’t fit, give each status a shape of its own, not only a colour.
- Write the ratio beside each status colour, at least 4.5:1 for its words and 3:1 for an icon with no word beside it.
- Draw the phone layout with each status word wrapping under the total, not dropped.
Passes
- Soft pill with an icon and the word The word sits on a pale tint of the status colour, set in a deep shade of it: #b42323 on #fdecec is 5.74:1, and #1e6b30 on #e7f5ea is 5.83:1. The tint keeps the colour coding; the word and the icon carry the meaning.
Rule of thumb: Say it in words, not only in the styling
- Orders grouped under what they need The failed order sits on its own under “Needs your attention”, above the rest under “Delivered”, so the heading says what each order needs and the dots only add to it. It suits a list where one status asks the customer to act.
Fails
- Colour stripe down the card’s edgeWCAG 1.4.1 A 4px stripe in the status colour down the left of each order card, as many dashboards draw it. The two cards differ only in the stripe’s hue, #e03131 against #2f9e44, which are 1.31:1 apart.
- Row tinted by its statusWCAG 1.4.1 A pale red or pale green fill behind the whole row, soft and current. The two tints, #fdecec and #e7f5ea, are 1.01:1 apart, so without their hue the two rows look the same.
Verify the fix
5 checks, no mouse.
Test with: Colour vision simulation, Contrast measurement, Zoom, Forced colors
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the status colours or the order list's layout change.
Limits
This is a starting pattern, not a guarantee for every application. Colour values are examples; measure your own palette against your real backgrounds. This guide covers a status shown by a coloured marker. Colour used alone in other places fails the same criterion and has its own guides: links in body text marked only by colour, required fields marked only by colour and form errors that don't say how to fix them. An instruction that points to something by its colour, "the orders in red need your attention", is covered in instructions that rely on colour, shape or position. A selected option shown by a fill alone, and chart lines told apart by colour, are the same failure and get their own guides later. Check the complete pages with people who rely on them.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.