Color Tools
Pick or paste a color and instantly see HEX, RGB, HSL and OKLCH side by side. Generate complementary, analogous, triadic, tetradic or monochromatic palettes. Verify foreground / background contrast against WCAG 2.2.
Color converter
Palette
Base + opposite hue (180°). Highest visual contrast — useful for accent / call-to-action pairings.
WCAG 2.2 contrast
17.40:1
Passes AAA
Learn More
HEX and RGB are device-coordinate spaces — they tell the screen how much of each phosphor to fire. They don't tell you anything useful about how a color will look next to another because the human eye doesn't perceive equal RGB steps as equal lightness changes. HSL is a step better but still not perceptually uniform: a 50% lightness yellow and a 50% lightness blue look very different in brightness. OKLCH defined by Björn Ottosson in 2020 is the first widely-adopted color space where Lightness (L) Chroma (C) and Hue (H) actually correspond to how the eye sees the color. Two OKLCH colors with the same L look equally bright. Hue rotations preserve perceived lightness. Chroma maps directly to vividness without the muddy mid-tones HSL produces. The practical payoff for design systems: you can build a 50/100/200/…/900 scale by stepping L from 0.95 down to 0.15 and the steps look perceptually even. You can rotate hue at fixed L+C and the resulting palette stays balanced. Tailwind v4 modern Linear and Vercel design systems and the CSS Color Module Level 4 spec all centre on OKLCH for tokens. The browser support story is also solid: oklch() works in every major engine since mid-2023. The converter here shows the same color in all four spaces so you can read the OKLCH coordinates and intuit which knob to turn.
Complementary uses two colors at opposite hues (180° apart). The contrast is maximal — useful for accent colors against a neutral base or for call-to-action buttons against a dominant brand color. Risky for body text where high chroma fights legibility. Analogous picks 3-5 hues within a 60° arc all close enough that they read as variants of one color. Best for low-tension backgrounds gentle gradients and brands that want to feel calm. Triadic spaces three colors 120° apart — vibrant balance used heavily in playful brand systems (Pixar MailChimp). Tetradic uses two complementary pairs (90° offsets) and is the hardest scheme to keep readable; if you reach for tetradic anchor it with strong neutral grey/white space so the four hues don't fight. Monochromatic is the underrated one — same hue varied L. This is what design tokens actually look like. Slack's purple scale Linear's blue scale and most enterprise design systems are monochromatic palettes by lightness. The picker here generates 5 lightness steps from a single base color which is exactly the shape you'd export to a Tailwind theme or CSS custom-property file. Pick any swatch to copy its HEX.
WCAG 2.2 §1.4.3 ('Contrast (Minimum)') is the most-litigated accessibility requirement. Two thresholds: 4.5:1 for normal text and 3:1 for large text (≥18pt regular OR ≥14pt bold). 'Pass AA' means hitting those. AAA the stricter level raises them to 7:1 and 4.5:1 respectively. The contrast ratio is computed from relative luminance — gamma-decoded sRGB channels weighted by the eye's spectral sensitivity (0.2126 R + 0.7152 G + 0.0722 B). The math handles ratio direction automatically: light text on dark and dark text on light produce the same number. In practice the place teams trip up is borderline grey-on-white. #777 on white is 4.48:1 — fails AA-normal by 0.02. #767676 hits 4.54:1 and passes. The picker here exposes the exact ratio with two decimals so you can debug those edge cases. WCAG Section 508 in the US the EU Accessibility Act and most enterprise procurement contracts now require AA across the entire site and the easiest way to ship that is to set up your design tokens so that any combination passes by construction — your dark text token always has ≥ 7:1 against your light background token and so on. The contrast checker here is the verifier; the design-system structure is the actual fix.
Frequently asked questions
Because they're different color models. HSL is a polar coordinate system over RGB — its 'lightness' is the average of the RGB components which doesn't match how the eye perceives brightness. OKLCH's lightness is calibrated against human visual response so two OKLCH colors with L=0.5 actually look equally bright while two HSL colors with L=50% might look wildly different (a yellow and a blue at HSL L=50% are visibly different brightnesses). For design tokens you want OKLCH because stepping L gives perceptually-even shades; for legacy compatibility you need HEX/RGB; for hand-rolled hue rotation HSL is fine. The converter shows all four so you can see which space best describes the relationship you're trying to express.
Relative luminance ratio of the lighter color over the darker plus a 0.05 offset to avoid divide-by-zero on pure black. Relative luminance gamma-decodes each sRGB channel then weights them by the eye's spectral sensitivity: 0.2126·R + 0.7152·G + 0.0722·B. White on black is 21:1 (the maximum); identical colors are 1:1. The 0.05 offset means the practical floor isn't quite 1:1 — pure black on near-black still gives ~1.05:1 not 1:1. The thresholds (4.5:1 AA-normal 7:1 AAA-normal) come from research on legibility under typical viewing conditions and are the same in WCAG 2.0 2.1 and 2.2 — the recent revisions changed other parts of the spec but not this number.
WCAG defines large text as ≥18pt regular OR ≥14pt bold. Converted to CSS pixels at the standard 96dpi: ≥24px regular or ≥18.66px bold. The threshold for large text is lower (3:1 AA-large 4.5:1 AAA-large) because larger letterforms are easier to discriminate at low contrast. In practice almost no body copy qualifies — most sites set body to 14-16px regular which means AA-normal (4.5:1) is what you need. Headings (28-48px) usually qualify as large and have a softer requirement but the visual hierarchy is so dominant on headings that you almost never want a low-contrast heading anyway.
Only if you're round-tripping through string formats. Pure greyscale colors have undefined hue — they're at the centre of the OKLCH cylinder where any angle is equivalent. The CSS spec says greyscale OKLCH should serialise the hue as none. The tool here outputs none for the hue value when chroma is below ~1e-7 which is the right behaviour. When you re-parse oklch(0.5 0 none) treat the hue as 0 and the resulting RGB is unambiguous. Most application code doesn't hit this; it's a footgun specifically for general-purpose color libraries.
Pick the monochromatic scheme — the tool generates 5 perceptually-spaced lightness steps from your base. To extend to a full 50/100/200/.../900 scale you'd parse the base into OKLCH fix the chroma and hue and step lightness from 0.95 (50) down to 0.15 (900) at perceptually-even intervals (linear in OKLCH L is approximately linear visually). Most modern design-system generators (Tailwind v4 themes Radix Colors ShadCN starter) do exactly this. The math is the same whether you generate it in this tool in a script or via the CSS color-mix() function with in oklab interpolation.
Two reasons. First RGB has 256 levels per channel — converting to HSL/OKLCH and back can introduce ±1 channel rounding error. The tool's tests tolerate this. Second OKLCH has a wider gamut than sRGB so an oklch() color picked from a wide-gamut display might map outside sRGB and get clamped on conversion. The clamping is honest (no fake interpolation) but it does change the visual color. For sRGB-only design systems work in HEX or RGB and use OKLCH only for the math; for wide-gamut design systems (Display P3 displays) consider using oklch() directly in CSS without the sRGB roundtrip.
The palette swatches copy individual HEX values when clicked. Programmatic export to Tailwind / CSS-vars / Figma JSON isn't built in — it's a 5-minute add but I haven't shipped it. If you need a structured export screenshot the palette and feed the HEX values into your tooling or open an issue and I'll prioritise. The five swatches are themselves the canonical output — paste each HEX into your tokens file under whatever names you use (primary accent brand-50/100/200/…).
More in Data Utilities
Developer validators, formatters and generators for structured data and identifiers.