Palettes · Ecommerce
Ecommerce colors one purchase flow, light and dark, checked for color vision
A shop asks color to do a lot: say what is on sale, what is in stock, which color you picked and what went wrong at checkout. Here each of those has a word or a shape as well, and every color is measured where it is used, in both themes and in four simulated visions.
- Contrast pairs, both themes
- 30
- Visions checked
- 4
- Meanings with a second carrier
- 7
The example
From product to checkout
Switch the theme and the vision. In grayscale the three stock colors nearly meet, and the shop still reads, because each has its word and its icon.
Simulated with Machado, Oliveira and Fernandes (2009); grayscale keeps luminance only. The shop is a picture: nothing in it can be pressed.
Autumn shop
Prices include tax
-
Sale −20%
Wool scarf
€32 Was
€40In stock
Add to basketColor: Forest
- Rust
- Forest
- Navy
-
Canvas tote
€24
Only 2 left
Add to basketColor: Rust
- Rust
- Forest
- Navy
-
Leather gloves
€45
Out of stock
Sold outEmail me when it is backColor: Navy
- Rust
- Forest
- Navy
Checkout
Postcode (required)
560001
Code AUTUMN applied: €8 off.
Total €48
Place orderPlace order is shown with keyboard focus.
Measured
What was checked
Every pair the shop puts on screen, in both themes. Text needs 4.5:1; the edges of fields and buttons and the focus ring need 3:1 (WCAG 1.4.3 and 1.4.11).
| Where it is used | Light | Dark | Needs |
|---|---|---|---|
| Names, prices and labels on a card | 13.38:1 | 15.76:1 | 4.5:1 |
| The old price and help text on a card | 5.64:1 | 6.24:1 | 4.5:1 |
| The sale price on a card | 5.27:1 | 5.18:1 | 4.5:1 |
| The word Sale on its badge | 4.55:1 | 4.55:1 | 4.5:1 |
| In stock: the word on a card | 6.26:1 | 10.38:1 | 4.5:1 |
| Only 2 left: the word on a card | 6.74:1 | 10.85:1 | 4.5:1 |
| Out of stock: the word on a card | 6.15:1 | 6.54:1 | 4.5:1 |
| A button’s words on its fill | 12.72:1 | 16.81:1 | 4.5:1 |
| A filled button against the card | 13.74:1 | 15.76:1 | 3:1 |
| A field’s border against the card | 4.52:1 | 4.25:1 | 3:1 |
| A field in error: its border and its message | 6.15:1 | 6.54:1 | 4.5:1 |
| A confirmation’s words on its tint | 5.87:1 | 8.95:1 | 4.5:1 |
| The focus ring against the card | 8.29:1 | 10.03:1 | 3:1 |
| A link on a card (also underlined) | 8.29:1 | 10.03:1 | 4.5:1 |
| The ring round the chosen color | 13.38:1 | 15.76:1 | 3:1 |
The sale color
A sale is good news, so it is not the error red. It is the Okabe–Ito vermilion: its badge tint is 12% of it in the card, and the word is walked in lightness until it reads at 4.5:1 on that tint. Beside the regular price it stays apart in every vision; the word Sale and the old price carry it anyway.
| Vision | Light: Closest pair | Dark: Closest pair |
|---|---|---|
| Typical vision | 32.1 Distinct | 38.2 Distinct |
| Protanopia | 24.7 Distinct | 40.2 Distinct |
| Deuteranopia | 31.4 Distinct | 33.7 Distinct |
| Tritanopia | 31.4 Distinct | 38.0 Distinct |
| Grayscale | 20.7 Distinct | 27.1 Distinct |
The three stock words, in each vision
The stock colors are the status colors. They come close in red–green simulations and nearly meet in grayscale: they are the third cue, after the word and the icon.
| Vision | Light: Closest pair | Dark: Closest pair |
|---|---|---|
| Typical vision | 13.2 Distinct | 28.8 Distinct |
| Protanopia | 4.4 Close match | 3.7 Close match |
| Deuteranopia | 4.1 Close match | 6.9 Noticeable |
| Tritanopia | 10.0 Noticeable | 21.5 Distinct |
| Grayscale | 0.4 Imperceptible | 1.0 Very close |
What carries each meaning besides color
| Meaning | Carried by |
|---|---|
| A product is on sale | A Sale badge with the saving, and the old price written as “Was €40” beside the new one |
| Whether it can be bought now | A word and an icon for each state; when it is out of stock the button says Sold out and cannot be pressed |
| Which color is chosen | A thick ring and a check mark on the swatch, and its name written above: “Color: Forest” |
| A field has a mistake | A message under the field that names the problem, an icon, and aria-invalid with aria-describedby |
| A field must be filled in | The word required in its label, not a red asterisk alone |
| Where the keyboard is | A 2-pixel ring at 3:1 or more round every control |
| Which words are a link | An underline |
Use them
The colors and the markup
The shop’s colors as CSS custom properties, then the markup for the four places color is most often asked to work alone.
:root {
--page: #F5F0E6;
--card: #FCF9F2;
--ink: #2F2B24;
--muted: #6A6357;
--control: #7A7263;
--action: #1D2A3E;
--on-action: #F5F0E6;
--focus: #1E40AF;
--link: #1E40AF;
--sale: #AD4B00;
--sale-bg: #F7E6D5;
--stock-in: #136B39;
--stock-low: #92400E;
--stock-out: #B91C1C;
--error: #B91C1C;
--success: #136B39;
--success-bg: #E8F5EE;
}
@media (prefers-color-scheme: dark) {
:root {
--page: #0F0E0C;
--card: #171613;
--ink: #F2EFE9;
--muted: #9D978D;
--control: #807A71;
--action: #F2EFE9;
--on-action: #0F0E0C;
--focus: #93C5FD;
--link: #93C5FD;
--sale: #DE6614;
--sale-bg: #2E1F11;
--stock-in: #4ADE80;
--stock-low: #E2C766;
--stock-out: #F87171;
--error: #F87171;
--success: #4ADE80;
--success-bg: #12281C;
}
}
<p class="price">
<span class="badge-sale">Sale −20%</span>
<span class="price-now">€32</span>
<span class="price-was">Was <s>€40</s></span>
</p>
<!-- The word carries the state; the icon and the color repeat it. -->
<p class="stock stock--low">
<svg aria-hidden="true" focusable="false" viewBox="0 0 16 16">…</svg>
Only 2 left
</p>
<fieldset class="variants">
<legend>Color</legend>
<label><input type="radio" name="color" value="rust"> <span class="swatch" style="--v:#B5532E"></span> Rust</label>
<label><input type="radio" name="color" value="forest" checked> <span class="swatch" style="--v:#2E6B4F"></span> Forest</label>
<label><input type="radio" name="color" value="navy"> <span class="swatch" style="--v:#1F3A5F"></span> Navy</label>
</fieldset>
<label for="email">Email (required)</label>
<input id="email" type="email" autocomplete="email"
aria-invalid="true" aria-describedby="email-error">
<p id="email-error" class="field-error">
<svg aria-hidden="true" focusable="false" viewBox="0 0 16 16">…</svg>
Enter an email address with a domain, such as [email protected].
</p>
Criteria
WCAG criteria it meets
Found a mistake? Write to us and we will correct it.