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.

Theme
View as

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 €40

    In stock

    Color: Forest

    • Rust
    • Forest
    • Navy
    Add to basket
  • Canvas tote

    €24

    Only 2 left

    Color: Rust

    • Rust
    • Forest
    • Navy
    Add to basket
  • Leather gloves

    €45

    Out of stock

    Color: Navy

    • Rust
    • Forest
    • Navy
    Sold outEmail me when it is back

Checkout

Email (required)

asha@mail

Enter an email address with a domain, such as [email protected].

Postcode (required)

560001

Code AUTUMN applied: €8 off.

Total €48

Place order

Place 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).

Contrast of every pair in the shop, in both themes
Where it is usedLightDarkNeeds
Names, prices and labels on a card13.38:115.76:14.5:1
The old price and help text on a card5.64:16.24:14.5:1
The sale price on a card5.27:15.18:14.5:1
The word Sale on its badge4.55:14.55:14.5:1
In stock: the word on a card6.26:110.38:14.5:1
Only 2 left: the word on a card6.74:110.85:14.5:1
Out of stock: the word on a card6.15:16.54:14.5:1
A button’s words on its fill12.72:116.81:14.5:1
A filled button against the card13.74:115.76:13:1
A field’s border against the card4.52:14.25:13:1
A field in error: its border and its message6.15:16.54:14.5:1
A confirmation’s words on its tint5.87:18.95:14.5:1
The focus ring against the card8.29:110.03:13:1
A link on a card (also underlined)8.29:110.03:14.5:1
The ring round the chosen color13.38:115.76:13: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.

The sale color
VisionLight: Closest pairDark: Closest pair
Typical vision32.1 Distinct38.2 Distinct
Protanopia24.7 Distinct40.2 Distinct
Deuteranopia31.4 Distinct33.7 Distinct
Tritanopia31.4 Distinct38.0 Distinct
Grayscale20.7 Distinct27.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.

The three stock words, in each vision
VisionLight: Closest pairDark: Closest pair
Typical vision13.2 Distinct28.8 Distinct
Protanopia4.4 Close match3.7 Close match
Deuteranopia4.1 Close match6.9 Noticeable
Tritanopia10.0 Noticeable21.5 Distinct
Grayscale0.4 Imperceptible1.0 Very close

What carries each meaning besides color

What carries each meaning besides color
MeaningCarried by
A product is on saleA Sale badge with the saving, and the old price written as “Was €40” beside the new one
Whether it can be bought nowA 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 chosenA thick ring and a check mark on the swatch, and its name written above: “Color: Forest”
A field has a mistakeA message under the field that names the problem, an icon, and aria-invalid with aria-describedby
A field must be filled inThe word required in its label, not a red asterisk alone
Where the keyboard isA 2-pixel ring at 3:1 or more round every control
Which words are a linkAn 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.

The colors, light then dark

: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;
  }
}

A sale price

<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>

Stock

<!-- 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>

A color picker that names the colors

<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>

A field with a mistake

<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.