Website Color Palette Guide

How to turn five good colors into a professional UI color system — roles, ratios, states, tokens and dark mode, with a copy-ready example.

A palette is five nice colors. A color system is those five colors with jobs, states and names — background, action, accent, text, border — so that every screen you build makes consistent decisions without you re-deciding anything. Most amateur sites have a palette; professional sites have a system. This guide shows how to build one, starting from any decent palette (if you don't have one yet, generate a starting point with the free AI color palette generator).

The 60-30-10 rule for interfaces

Borrowed from interior design, the rule budgets visual weight: about 60% of the interface is neutral background and surfaces, about 30% is the secondary brand presence, and roughly 10% is accent. On a website that maps cleanly: backgrounds, cards and body text dominate; the primary color appears in navigation, buttons and links; the accent is reserved for the single most important action in view.

The ratio's real value is restraint. If 40% of the screen wears your accent color, nothing is the accent anymore — strong colors persuade only when they're scarce.

Concrete mapping for a typical marketing page: the 60% is the page background, card surfaces and all body text; the 30% is the primary color at work — header actions, links, secondary buttons, illustration; the 10% is the accent, spent on one hero button and one highlight. If you're starting from a five-color palette of the kind the generator produces (three chromatic colors plus a light and a dark neutral), the two neutrals naturally form the 60%, the primary and secondary take the 30%, and the accent takes the 10%.

Assign semantic roles

Every color in the system needs a name that describes its job, not its appearance. Six roles cover almost every interface:

Background & surface

The canvas everything sits on, plus card and panel layers above it. Keep it low-saturation and high-lightness (tinted with the brand hue, never pure gray), and make sure body text on it clears contrast with room to spare — this pair is the backbone of the whole system.

Primary / action color

Buttons, links, active navigation. It carries two contrast duties: label text on top of it must reach 4.5:1, and the button itself needs 3:1 against the background when its boundary is the only thing identifying it as interactive.

Secondary / support

Section backgrounds, secondary buttons, illustrations and charts. Usually a lighter, darker or desaturated sibling of the primary — close enough to feel related, far enough not to compete.

Accent / highlight

Badges, highlights and the one call-to-action that matters most. A hue distinct from the primary, and still 3:1 against adjacent surfaces whenever it communicates information.

Text & muted text

Main text is a near-black tinted with the brand hue. Muted text — timestamps, captions, helper copy — still has to hit 4.5:1; it's the role where palettes fail most often, because "subtle" quietly becomes "unreadable".

Borders & dividers

Decorative separators can be quiet, but functional boundaries — input outlines, checkbox edges, focus rings — need 3:1 against what they sit on (the WCAG contrast guide details which cases count).

Build a professional UI color system

With roles assigned, three mechanisms turn the palette into a system: named tokens, derived states and fixed feedback colors.

Design tokens

Encode each role as a named token: --color-primary, not --color-violet-600. Role-based names survive redesigns — when the brand swaps violet for teal, the code changes values, not names, and every button, alert and chart updates from one place. If you also want raw scales (a 50–950 shade ramp per hue), keep them as a separate layer that the semantic tokens point at, so components never consume raw scale values directly.

Interactive states

Derive states instead of guessing at them. Hover: shift the base color's lightness a step darker (lighter on dark backgrounds). Active: one more step in the same direction. Focus: a visible ring in the primary or accent, checked at 3:1. Disabled: desaturate and reduce opacity, but keep the control perceivable — WCAG exempts disabled controls from contrast rules, yet users still need to find them. Because states stay within the base color's hue, transitions between them feel smooth instead of jumpy, and the CSS stays short: one formula per state, applied everywhere.

Feedback colors

Success, warning and error need hues nobody has to decode: green, amber and red. Sensible defaults are #16A34A, #D97706 and #DC2626, all readable on light backgrounds. Re-derive them when your palette is unusually saturated or dark: shift them toward your brand hue family, adjust lightness until labels on them pass contrast, and make sure success and error remain distinguishable for color-blind users by pairing each with an icon, never color alone.

Dark mode without doubling your work

Because the tokens are semantic, dark mode is a re-mapping, not a redesign. Flip the roles: backgrounds become deep surfaces tinted with the brand hue (a dark violet, not pure black), text becomes a tinted near-white, and borders lighten slightly. A practical way to derive the dark surfaces is to reuse the light ones' HSL values with the hue kept and the lightness dropped — a background at roughly 97% lightness becomes its counterpart near 10–14%, with saturation dialed back so large dark areas don't vibrate. The primary color usually needs a lightness bump to keep white label text at 4.5:1 on it, and the feedback colors brighten a step. Re-test every pair — ratios that passed on light backgrounds will not all pass on dark ones, and this is the step most dark modes skip.

Example: tokens from a 5-color palette

Here's a complete token set built from a violet palette of the kind the generator produces — three chromatic colors plus tinted neutrals, with standard feedback colors added:

:root {
  --color-primary: #7C3AED;
  --color-secondary: #EC4899;
  --color-accent: #F59E0B;      /* pairs with dark text — white fails contrast here */
  --color-background: #F5F3FF;
  --color-surface: #FFFFFF;
  --color-text: #241E38;
  --color-muted: #6B6480;
  --color-border: #E8E4F2;
  --color-success: #16A34A;
  --color-warning: #D97706;
  --color-error: #DC2626;
}

Notice the structure: names describe roles, every role from the list above is present, and the neutrals carry a violet tint (#F5F3FF, #241E38) so the system feels like one family. The accent comment matters in practice — bright accents often fail with white labels, so the token block is where you record that decision. That's a palette and a system in eleven lines.

Test, preview, export

Close the loop the same way you opened it — in the browser. Check every text/background pair with the contrast checker's live ratios and pass badges, judge the palette on a real layout in the live website preview, and then export straight to design tokens or CSS variables with the token export. If you're unsure which export format fits your stack, the FAQ compares them.

And when you need the theory underneath — why a secondary belongs 30° away, or what triadic actually means — the color theory guide covers the harmony math with worked examples.

Put the system to work: open the free AI color palette generator, lock the colors you like and export the whole thing as tokens in one pass.