Elements must meet minimum color contrast ratio thresholds

Text that is too pale against its background is hard or impossible to read for customers with low vision, colour blindness or ageing eyes, and for anyone using a phone in sunlight. Prices, discount codes, form hints and button labels that cannot be read lead to mistakes and lost orders.

Rule id
color-contrast
Source
axe-core 4.13.0
Impact
Serious
Fix tier
ASSISTED
on Shopify, Shopware, WooCommerce and Magento
Status
runs

What the check does

Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds

Candidates are elements with a visible text node of their own, plus input, select and textarea fields, even empty ones, except a select without options and a field whose text-indent moves its text off the control. Skipped are textless inputs such as checkboxes, disabled or inert elements, labels of disabled controls, and text of only emoji or punctuation.

The check reads the computed text color and builds the background from the elements stacked behind the text, blending semi-transparent layers onto a white page. Text counts as large from a font-size of 18pt (24px), or 14pt (18.66px) when font-weight is 700 or more.

When the check cannot decide, the result is needs review, as with a background image or gradient, an image or video behind the text, another element on top, a large, absolutely positioned ::before or ::after with a background, or a single failing character. Validiscan’s scanner does not turn these into findings, so such text needs a person’s check.

Colors are read in the state the page loads in, with the light color scheme, at each scanned viewport. vs-hover-focus-contrast measures hover and focus states.

How to fix it

Raise the contrast of normal text to at least 4.5:1 and of large text (24px, or 18.66px bold) to at least 3:1. Adjust the colour in the theme settings or CSS variables rather than per element, keeping the brand hue and changing the lightness, and check text on images and sale badges too.

WCAG success criteria

EN 301 549 clauses

The EN 301 549 clause of each criterion, by version of the standard
WCAG criterion Version 3.2.1 Version 4.1.1
1.4.3 9.1.4.3 9.1.4.3

Recipes that list this rule

This rule has the tier ASSISTED. In a project, a finding of it takes the ASSISTED way, and these recipes are not applied to it.

Shopify: recipe contrast-tokens

Show the before and after (1)
Before and after Example data

assets/base.css.liquid Changes to assets/base.css.liquid: 3 added, 3 removed

Changes to assets/base.css.liquid: 3 added, 3 removed
Line before Line after Change Code
745 745 font-size: 0.8125rem;
746 746 letter-spacing: 0.04em;
747 747 text-transform: uppercase;
748 Removed color: #929292;
748 Added color: #767676;
749 749 }
750 750
751 751 .rating {
1013 1013
1014 1014 .copyright__content {
1015 1015 margin: 0;
1016 Removed color: #929292;
1016 Added color: #6f6f6f;
1017 1017 }
1018 1018
1019 1019 .policies {
1077 1077
1078 1078 .cookie-banner__text,
1079 1079 .cookie-banner__link {
1080 Removed color: #9a9a9a;
1080 Added color: #767676;
1081 1081 }
1082 1082
1083 1083 .cookie-banner__icon-button {

Shopware: recipe contrast-tokens

Show the before and after (1)
darkens the unit price colour to 4.5:1 with the same hue; axe clears it on both pages Example data

Resources/app/storefront/src/scss/_variant-broken.scss Changes to Resources/app/storefront/src/scss/_variant-broken.scss: 1 added, 1 removed

Changes to Resources/app/storefront/src/scss/_variant-broken.scss: 1 added, 1 removed
Line before Line after Change Code
45 45 /* Light grey unit prices, 3.1:1 (color-contrast). */
46 46 .product-price-unit,
47 47 .product-detail-price-unit {
48 Removed color: #929292;
48 Added color: #757575;
49 49 }
50 50
51 51 /* Fixed two-line product names (vs-text-spacing). */

WooCommerce: recipe contrast-tokens

Show the before and after (1)
darkens the footer text colour when every element it styles was measured Example data

assets/css/main.css Changes to assets/css/main.css: 1 added, 1 removed

Changes to assets/css/main.css: 1 added, 1 removed
Line before Line after Change Code
676 676 .kb-footer-about,
677 677 .kb-footer-newsletter-intro,
678 678 .site-info {
679 Removed color: #888;
679 Added color: #6e6e6e;
680 680 }
681 681
682 682 .site-footer ul.menu {

Magento: recipe contrast-tokens

Show the before and after (1)
darkens the single #929292 token and validates Example data

app/design/frontend/Validiscan/fixture/web/css/source/_theme.less Changes to app/design/frontend/Validiscan/fixture/web/css/source/_theme.less: 1 added, 1 removed

Changes to app/design/frontend/Validiscan/fixture/web/css/source/_theme.less: 1 added, 1 removed
Line before Line after Change Code
1099 1099 // VALIDISCAN-SEEDED color-contrast: #929292 on white is 3.1:1.
1100 1100 .block-promo .info,
1101 1101 .toolbar-amount {
1102 Removed color: #929292;
1102 Added color: #767676;
1103 1103 }
1104 1104
1105 1105 // VALIDISCAN-SEEDED vs-reflow: the promo row keeps a 1100px minimum width at every breakpoint.

app/design/frontend/Validiscan/fixture/web/css/styles-m.css Changes to app/design/frontend/Validiscan/fixture/web/css/styles-m.css: 1 added, 1 removed

Changes to app/design/frontend/Validiscan/fixture/web/css/styles-m.css: 1 added, 1 removed
Line before Line after Change Code
1075 1075
1076 1076 .block-promo .info,
1077 1077 .toolbar-amount {
1078 Removed color: #929292;
1078 Added color: #767676;
1079 1079 }
1080 1080
1081 1081 .block-promo-wrapper {

Start with a free check of your shop.

Send your shop’s address. Validiscan scans it and replies with every failure the scan can prove, with the page and the code.

Request a free check

Or write to info@validiscan.com.

What the free check covers, and what it leaves out
You send
your shop’s address
Pages scanned
up to 15
You get
every failure the scan can prove, with the page and the code
On your shop
public pages only; no login, nothing bought, no forms sent
What it is not
a full audit

Write to Validiscan

For a free check, give the address of your shop and its platform.

Validiscan uses what you send to answer you. Privacy notice