You have a color palette. Now you need to assign it across your app. Which color goes on the background? Which one goes on the sidebar? Which one goes on the button?
The 60-30-10 rule gives you that answer. It tells you exactly how to distribute three colors across a UI so the layout feels intentional instead of random.
Not sure which colors to start with? Read how to choose a color palette for your app first.
Generate your palette at sixtythirtyten.co →
The problem: which color goes where?
Say you're building a SaaS dashboard. You've chosen three colors:
- A light off-white (
#f8fafc) - A dark slate (
#1e293b) - A blue for interactive elements (
#3b82f6)
Most developers drop these onto the page by feel. If you want ready-to-use hex palettes that already follow the rule, see 60-30-10 hex color palette examples. The result usually ends up with the accent color on too many elements — buttons, headings, icons, borders — until nothing stands out.
The 60-30-10 rule fixes this by assigning each color a weight:
- 60% — your dominant color. Covers the most surface area.
- 30% — your secondary color. Provides structure and contrast.
- 10% — your accent color. Reserved exclusively for actions and focus points.
The goal of the rule is contrast through scarcity. When your blue only appears on primary buttons and active states, users immediately recognize it as "this is where I act." When it appears everywhere, it stops signaling anything.
The rule as a layout map
Here is how the three roles map to real UI regions in a SaaS app:
Dominant (60%) — main content area and backgrounds
- Page background
- Card surfaces
- Content area white space
- Form field backgrounds
This is usually your lightest, most neutral color. It sets the visual tone without competing for attention.
Secondary (30%) — structure and navigation
- Sidebar background
- Top navigation bar
- Footer
- Section dividers
- Table header rows
Your secondary color creates visual grouping. It frames the content without drawing clicks.
Accent (10%) — calls to action and active states
- Primary CTA buttons
- Active navigation item
- Selected tab indicator
- Notification badge
- Links in body copy
Your accent color appears rarely. Every time it does, it means "do something here."
Implementation: CSS custom properties
The cleanest way to wire this up is three custom properties in globals.css. See the CSS variables color system cheat sheet for a copy-paste reference:
:root {
--color-dominant: #f8fafc;
--color-secondary: #1e293b;
--color-accent: #3b82f6;
}
Use them across your HTML with var() references:
<body style="background: var(--color-dominant);">
<nav style="background: var(--color-secondary);">
<a href="/dashboard" style="color: var(--color-dominant);">Dashboard</a>
</nav>
<main>
<button style="background: var(--color-accent); color: white;">
Create project
</button>
</main>
</body>
Custom properties give you one place to swap the entire palette. Change --color-accent from blue to green and every button, badge, and active state updates simultaneously.
To support dark mode, add an override block. For a deeper treatment of dark mode palette decisions, see 60-30-10 dark mode color palette:
:root {
--color-dominant: #f8fafc;
--color-secondary: #1e293b;
--color-accent: #3b82f6;
}
.dark {
--color-dominant: #0f172a;
--color-secondary: #1e293b;
--color-accent: #60a5fa;
}
Implementation: Tailwind config
Tailwind v4 uses a @theme block in your CSS file to register design tokens as utility classes. For a complete reference on both v4 and v3 syntax, see the Tailwind color palette guide:
@theme {
--color-dominant: #f8fafc;
--color-secondary: #1e293b;
--color-accent: #3b82f6;
}
This registers bg-dominant, text-secondary, bg-accent, and every other Tailwind color utility automatically.
For Tailwind v3, extend the colors key in tailwind.config.ts:
import type { Config } from "tailwindcss";
const config: Config = {
theme: {
extend: {
colors: {
dominant: "#f8fafc",
secondary: "#1e293b",
accent: "#3b82f6",
},
},
},
};
export default config;
Both approaches give you the same utility classes:
<div class="bg-dominant">
<nav class="bg-secondary">
<button class="bg-accent text-white">Create project</button>
</nav>
</div>
Real example: SaaS dashboard
Here is a complete layout applying all three roles. This is a Next.js app shell — sidebar, header, and a main content area. For production-ready dashboard palette examples with full CSS and Tailwind, see SaaS dashboard color palette: CSS and Tailwind:
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex h-screen bg-dominant">
{/* Sidebar — secondary color (30%) */}
<aside className="w-64 bg-secondary flex flex-col">
<div className="px-6 py-4">
<span className="text-dominant font-semibold text-lg">Acme</span>
</div>
<nav className="flex-1 px-4 space-y-1">
{/* Active nav item uses accent */}
<a
href="/dashboard"
className="flex items-center gap-3 px-3 py-2 rounded-md
text-dominant bg-accent/20 text-accent font-medium"
>
Dashboard
</a>
{/* Inactive nav items use muted dominant text */}
<a
href="/projects"
className="flex items-center gap-3 px-3 py-2 rounded-md
text-dominant/60 hover:text-dominant"
>
Projects
</a>
<a
href="/settings"
className="flex items-center gap-3 px-3 py-2 rounded-md
text-dominant/60 hover:text-dominant"
>
Settings
</a>
</nav>
</aside>
{/* Main area — dominant color (60%) */}
<main className="flex-1 flex flex-col overflow-hidden">
{/* Header — secondary background */}
<header className="h-14 bg-secondary/10 border-b border-secondary/20
flex items-center justify-between px-6">
<h1 className="text-secondary font-semibold">Dashboard</h1>
{/* Primary CTA — accent color (10%) */}
<button className="bg-accent text-white px-4 py-2 rounded-md
text-sm font-medium hover:bg-accent/90">
New project
</button>
</header>
{/* Content — dominant background */}
<div className="flex-1 overflow-y-auto p-6">
{children}
</div>
</main>
</div>
);
}
Notice the accent color only appears in two places: the active nav state and the primary CTA button. Everything else uses dominant or secondary. That scarcity is what makes the blue button stand out without additional styling work.
Common mistakes
Using accent on decorative elements. If your accent color appears on icon backgrounds, card borders, or section headings, it loses its signal. Accent means "take action here." Keep it exclusive.
Choosing similar dominant and secondary colors. If both colors are near-white, there is no visual grouping between your content area and your navigation. Push your secondary darker or more saturated to create clear separation.
Skipping the tokens. Hard-coding hex values directly in components means a palette swap requires hunting through every file. Use CSS custom properties or Tailwind config so the colors live in one place.
Forgetting contrast ratios. The rule assigns proportions, not accessibility. Check that your text over dominant and secondary backgrounds meets WCAG AA (4.5:1 for normal text). Tools like WebAIM's Contrast Checker verify this in seconds.
Generate your palette at sixtythirtyten.co →
Enter one color and get a 60-30-10 palette with the CSS variables and Tailwind config already written. Drop it into your project and start building.