Color Theory Basics for Developers
The color wheel rules design school teaches, translated into the hue-angle math you can actually implement, plus the RYB-vs-RGB gotcha nobody warns you about.
Most color theory was formalized long before screens existed, and the traditional teaching still uses the artist's "RYB" wheel (red, yellow, blue as primaries) — which does not map cleanly onto the RGB or HSL wheel your CSS actually uses. This mismatch is why a "complementary" pairing you learned in an art class can look off when you try to reproduce it with hue-plus-180° math in code. Here's the developer-facing version: what each classic relationship actually is in hue-angle terms, and where the two wheels genuinely disagree.
The RYB vs. RGB wheel problem, up front
On the traditional RYB wheel, orange sits opposite blue, and that pairing is taught as the classic "complementary" example. On the RGB/HSL wheel that browsers and design tools actually compute against, hue 0° is red, and the true 180°-opposite of orange (roughly hue 30°) is around hue 210° — a blue, but not necessarily the exact blue an RYB-trained eye would expect, because the two wheels place primaries at different angular positions (RYB puts red/yellow/blue at 0°/120°/240°-equivalent slots; RGB/HSL puts red/green/blue at 0°/120°/240°). If you've ever generated a "complementary" pair programmatically and felt it looked subtly wrong compared to a traditional color wheel poster, this is almost always why. Everything below uses the RGB/HSL wheel, because that's what the color harmonies tool and any programmatic palette generator actually computes against.
Complementary — 180° apart
The simplest relationship: take a hue, add 180°, wrap around 360 if needed. hsl(9, 100%, 64%) (tomato red, roughly hue 9°) pairs with roughly hue 189°, a cyan-leaning blue. Complementary pairs produce the maximum possible hue contrast, which makes them excellent for a single small accent against a dominant base color (a call-to-action button on an otherwise neutral page) but risky as two large, equal-weight fields — high-contrast complementary pairs at similar saturation and lightness can visually "vibrate," an actual perceptual effect from simultaneous contrast, not just a stylistic complaint. See it applied to real named colors at what goes with Tomato or what goes with Slateblue.
Analogous — hues within ~30–60° of each other
Analogous schemes pick three or four hues clustered close together on the wheel — say, hue 200°, 220°, and 240°, three related blues. Because the hues are close, analogous palettes read as naturally harmonious with very little effort; the risk runs the other direction from complementary schemes — with hues this close, the only thing separating your colors is saturation and lightness, so if you don't vary those deliberately, the palette can read as flat or under-differentiated rather than harmonious. A good analogous ramp typically pairs the tight hue range with genuine spread in lightness — see the shades, tints & tones generator for building that spread deliberately rather than by eye.
Triadic — three hues 120° apart
Evenly split the wheel into thirds: hue 0°, 120°, 240° is the canonical example (in RGB terms, that's literally red, green, and blue's primary positions). Triadic schemes are vibrant and balanced by construction — no single hue dominates — which is why they show up often in illustration, editorial branding, and any context that wants three colors of genuinely equal visual weight rather than a primary-plus-two-accents hierarchy. The tradeoff is that vibrancy: at high saturation, triadic schemes can feel loud or juvenile, so production use often pulls saturation down on two of the three hues while keeping the third at full intensity as the dominant color.
Split-complementary — a base plus both neighbors of its complement
Take a base hue, find its 180° complement, then use the two hues 30° on either side of that complement instead of the complement itself — base hue 0°, split-complement hues roughly 150° and 210°. This gets most of a complementary pair's contrast with less of its visual tension, because neither of the two secondary hues is a full 180° away from the base. It's a good middle ground when a straight complementary pair feels too aggressive but an analogous scheme feels too safe.
Monochromatic — one hue, varied lightness and saturation
Not always covered in the "harmony wheel" conversation because it doesn't involve multiple hues at all, but it's a legitimate and common real-world choice: pick one hue, vary only lightness and saturation to build the full palette. This guarantees harmony by construction (there's no hue relationship to get wrong) and is common in minimal or brand-disciplined UIs where a single accent color needs to carry buttons, links, badges, and highlights without introducing a second hue at all. The tradeoff is expressive range — monochromatic palettes can struggle to visually separate unrelated categories (like chart series) since they're all variations on one hue.
Implementing this without eyeballing it
Every relationship above reduces to arithmetic on the hue channel once you're in HSL or OKLCH: add/subtract a fixed degree offset, optionally adjust saturation or lightness, wrap the result into 0–360°. That's exactly what the color harmonies tool automates from a single input hex — feed it your base color and get complementary, analogous, triadic, and split-complementary sets computed rather than guessed. If you're generating ramps rather than harmony sets specifically, note that HSL's lightness channel doesn't track perceived brightness evenly across hues, which can make hue-rotated triadic or analogous sets feel uneven in "weight" even at identical saturation/lightness numbers — what OKLCH is and why it matters covers the fix. And once you have hues you like, checking that any pairing intended to carry text also clears WCAG contrast is a separate, mandatory step — harmony and accessibility are independent axes; see choosing an accessible color palette for combining both. For a closer comparison of the two most commonly confused relationships, see complementary vs. analogous colors.
A note on saturation and lightness, which the wheel alone doesn't capture
Everything above is phrased purely in terms of hue angle, but hue is only one of the three HSL dimensions, and harmony relationships computed on hue alone can still misfire if saturation and lightness aren't considered too. Two colors that are a textbook 180° complementary pair in hue can still look mismatched if one is fully saturated and the other is washed out — the hue relationship is "correct" but the overall pairing doesn't read as intentional. A reliable pattern for production palettes: pick the hue relationship first (complementary, analogous, triadic, whichever fits the use case), then deliberately match or intentionally vary saturation and lightness across the set — matched for a cohesive, same-weight palette; deliberately varied when you want one color to read as dominant and the others as supporting. This is a design decision the harmony math itself doesn't make for you, and skipping it is the most common reason a mathematically-correct harmony set still looks "off" next to a hand-picked one from an experienced designer.
Named colors as a starting point instead of a blank hue wheel
If you'd rather start from a real, already-named color than an arbitrary hue-angle number, this site's 1,094 named-color pages — spanning the 148 standard CSS/X11 names and 946 more from the xkcd color-naming survey — each link out to their own harmony set. Coral, Slateblue, and Chartreuse are three that sit in different, useful parts of the wheel if you want real reference points rather than a hex value pulled from nowhere.