Every time you pick colors for a project by eyeballing it, you're ignoring geometry that would give you better results in less time. Color harmony isn't subjective. It's angular relationships on a wheel, and once you understand the math, you stop guessing.
Complementary colors sit 180 degrees apart. Analogous colors are within 30 degrees. Triadic colors form an equilateral triangle at 120-degree intervals. These aren't aesthetic opinions. They're spatial relationships in the HSL color model that consistently produce palettes that work.
HSL: The Color Model That Makes Sense
RGB is how screens render color. HSL is how humans think about it. Hue is the angle on the color wheel (0 to 360 degrees), saturation is the intensity (0% to 100%), and lightness controls how bright or dark the color appears (0% is black, 100% is white, 50% is the pure color).
When you work in HSL, generating color schemes becomes arithmetic. Red is 0 degrees. Orange is around 30. Yellow is 60. Green sits at 120, cyan at 180, blue at 240, and purple at 300. If your brand color is hsl(240, 70%, 50%), you already know its complement is hsl(60, 70%, 50%) because you just add 180.
This is why designers who understand HSL work faster than designers who drag color pickers around looking for something that "feels right."
The Schemes and Their Geometry
A complementary scheme uses two colors separated by 180 degrees. High contrast, high energy. It works well for call-to-action elements against a background. The danger is using both colors at equal volume, which creates visual vibration and is exhausting to look at.
Analogous schemes use colors within 30 degrees of each other. Pick your base hue, then go 30 degrees in each direction. These palettes feel harmonious and natural because the colors share underlying tones. Most nature photography has an analogous palette. The risk is low contrast, which makes the design feel flat if you don't vary lightness enough.
Triadic schemes place three colors at 120-degree intervals. Start at any hue, add 120, add 120 again. This gives you three colors with strong visual contrast that still feel balanced. Primary colors (red, blue, yellow) are a triadic scheme. It's bold and works well for illustration and branding, but it's hard to use in UI without overwhelming the user.
Split-complementary is my go-to for web projects. Take your base color, find its complement (180 degrees opposite), then instead of using the complement directly, use the two colors 30 degrees on either side of it. So if your base is at 0 degrees, instead of the complement at 180, you use 150 and 210. You get the contrast benefits of complementary without the visual tension.
The 60-30-10 Rule
This ratio comes from interior design and it translates directly to interfaces. 60% of your visual space uses your dominant color (usually the lightest, most neutral option). 30% uses your secondary color. 10% uses your accent.
Look at any well-designed SaaS landing page and you'll see this breakdown. The background and large surfaces take up 60%. Navigation, cards, and secondary elements take 30%. Buttons, links, and highlights get the remaining 10%.
This is why Netflix works visually. The dominant color is black (the background). The secondary is dark gray (cards, the nav bar). The accent is red (the logo, play buttons, profile highlights). If Netflix used red for 60% of the interface, you'd close the tab in three seconds.
Accessible Contrast
WCAG AA requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text. WCAG AAA bumps that to 7:1 and 4.5:1 respectively.
In practice, this means your carefully chosen palette might fail accessibility requirements. A common problem: light blue text on a white background. It looks fine on your high-end monitor in a dark room. It's unreadable on a cheap laptop in sunlight.
The contrast ratio formula uses relative luminance, which weights green heavily (the human eye is most sensitive to green). Pure blue (#0000FF) on white has a contrast ratio of 8.59:1, which passes AAA. But a medium blue (#4488CC) on white drops to 3.67:1, which fails AA for normal text.
You can fix this without changing your hue. Adjust lightness in HSL. Dropping the lightness value of that medium blue from 50% to 35% can push you past the 4.5:1 threshold while keeping the same hue and saturation. This is another reason HSL is the better mental model: you can fix accessibility issues by tweaking one value instead of guessing at RGB combinations.
CSS Custom Properties for Palette Management
Define your palette once and reference it everywhere:
:root {
--color-primary-h: 240;
--color-primary-s: 70%;
--color-primary-l: 50%;
--color-primary: hsl(var(--color-primary-h), var(--color-primary-s), var(--color-primary-l));
--color-primary-light: hsl(var(--color-primary-h), var(--color-primary-s), 70%);
--color-primary-dark: hsl(var(--color-primary-h), var(--color-primary-s), 30%);
}
By storing hue, saturation, and lightness as separate variables, you can generate light and dark variants without defining entirely new colors. Changing your entire color scheme means updating three values instead of hunting through a stylesheet.
Putting It Together
I built a palette generator at zovo.one that lets you pick a base color and generates complementary, analogous, triadic, and split-complementary schemes with contrast ratios calculated against white and black backgrounds. It exports CSS custom properties so you can drop the palette straight into a project.
But honestly, the tool is secondary. The real value is understanding that color harmony is math, not instinct. Once you internalize the degree relationships, you start seeing them everywhere, and your design decisions get faster and more consistent.
I'm Michael Lip. I build free developer tools at zovo.one. 350+ tools, all private, all free.
Top comments (0)