Color Palette Generator
Start from a base color and get accessible palettes, contrasts, and shades for UI and brand.
Derive complementary, analogous, triadic, and monochromatic sets from a base colour and read every swatch as HEX, RGB, and HSL. A grid that looks balanced side by side can still fail an accessibility audit, because the lightness channel in HSL has very little to do with how light a colour actually looks to the eye. This page covers the maths that decides which pairings survive.
The three contrast thresholds and what counts as large text
WCAG 2.2 sets three numbers worth memorising. Success Criterion 1.4.3 Contrast (Minimum), at Level AA, requires 4.5:1 for body text and 3:1 for large text. Success Criterion 1.4.6 Contrast (Enhanced), at Level AAA, raises those to 7:1 and 4.5:1. Success Criterion 1.4.11 Non-text Contrast, also Level AA, requires 3:1 for user interface components and for graphical objects that carry meaning.
"Large" has a precise definition and it is larger than most people assume: at least 18 point, which is roughly 24 CSS pixels, or 14 point bold, roughly 18.66 pixels. A 20px heading is not large text and still needs 4.5:1. Getting this wrong is the most common way a palette passes an informal check and fails a real audit.
1.4.11 is the criterion palettes fail most often, because it applies to things designers do not think of as text: input borders, focus indicators, toggle states, icon-only buttons, and the individual series in a chart. A 1.8:1 hairline border around a text field looks restrained and is functionally invisible to a substantial number of users. Two exemptions are worth knowing — text that is part of an inactive, disabled component has no contrast requirement, and neither does purely decorative imagery. Placeholder text gets no such exemption; it is live content and must meet 4.5:1.
Relative luminance, and why green carries most of it
A contrast ratio is (L1 + 0.05) / (L2 + 0.05), where L1 is the relative luminance of the lighter colour and L2 of the darker. The scale runs from 1:1 for two identical colours to 21:1 for pure black against pure white. The 0.05 on both sides models ambient light reflecting off the screen, which is why the maximum is 21 rather than infinity.
Relative luminance itself is 0.2126R + 0.7152G + 0.0722B, but only after each channel has been linearised. Divide the 8-bit value by 255, then if the result is at most 0.04045 divide it by 12.92, otherwise raise ((c + 0.055) / 1.055) to the power 2.4. That gamma step is what makes the relationship non-linear; doubling a hex value does not double its luminance. WCAG used a threshold of 0.03928 before May 2021, and the change to 0.04045 makes no practical difference at 8-bit precision.
Look at the coefficients. Green contributes 71.52% of the luminance and blue only 7.22%. Adjusting the blue channel of a colour barely moves its contrast ratio at all, while a small change to green moves it a lot — useful when you are trying to nudge a brand colour over a threshold without visibly changing it. One more trap: the formula takes no account of alpha. A translucent overlay must be composited against its real backdrop before you measure. rgba(0, 0, 0, 0.6) over white is #666666, and #666666 is what you test.
Equal HSL lightness, wildly different contrast
Take two colours at identical positions on the HSL lightness axis. hsl(60 100% 50%) is #FFFF00; hsl(240 100% 50%) is #0000FF. Both sit at exactly 50% lightness. Against a white background, the yellow gives a contrast ratio of about 1.07:1 and the blue about 8.59:1 — an eightfold difference from the same slider position, and the yellow is effectively invisible.
Against black the ranking inverts: the yellow reaches roughly 19.6:1 while the blue manages only about 2.4:1, which misses even the 3:1 non-text threshold. That is the whole problem with HSL in one example. Its L is a geometric coordinate in a cylinder built on top of sRGB, not a measure of perceived brightness, and it ignores the luminance weighting entirely.
The practical consequence for generated ramps: this tool builds its monochromatic scale by stepping HSL lightness in fixed increments and clamping the result to a 10–90 range, which produces evenly spaced numbers rather than evenly spaced appearances. A step-three swatch in a yellow ramp and a step-three swatch in a blue ramp are not interchangeable, and a token scale that assumes they are will pass in one hue and fail in another. Treat the output as a starting grid, then check every foreground and background pairing you actually intend to ship.
Perceptually uniform ramps and the sRGB gradient dead zone
Oklab, and its polar form OKLCH, were designed by Björn Ottosson in 2020 specifically to fix the problem above: equal numeric steps in lightness are intended to look like equal steps to the eye, across every hue. Both are defined in CSS Color Module Level 4 and shipped in Safari 15.4, Chrome and Edge 111, and Firefox 113, making them widely available since May 2023. Building a ramp by holding chroma and hue steady while stepping OKLCH lightness gives you a scale where the same index means the same visual weight in blue as in yellow.
The same maths explains the grey dead zone in gradients. CSS interpolates gradients in sRGB by default, and a straight line between two saturated, roughly opposite hues passes near the desaturated centre of the colour cube — blue to yellow is the classic demonstration, producing a muddy grey band in the middle. Writing linear-gradient(in oklch, blue, yellow) travels around the hue circle instead of through the middle and keeps chroma up the whole way.
Wide gamut is the remaining wrinkle. OKLCH can describe colours sRGB cannot reproduce, so a high chroma value gets gamut-mapped by the browser, and two values you specified as distinct can clip to the same displayable colour. Display P3 covers roughly 25% more area than sRGB, so if you want that extra saturation, express it as color(display-p3 ...) behind an @media (color-gamut: p3) query with an sRGB fallback — otherwise the palette flattens on any ordinary monitor.
Colour-vision deficiency and the hue-only trap
Red-green colour vision deficiency affects roughly 8% of men and 0.5% of women of northern European descent — about one in twelve male visitors. Deuteranomaly, a shifted green response, is the most common form. These users are not seeing a greyscale version of your interface; they are seeing a compressed one, in which specific hue pairs that look obviously different to you converge.
WCAG addresses this at Level A, the lowest conformance tier, in Success Criterion 1.4.1 Use of Color: colour must not be the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. A table with red and green status cells and no other differentiator fails the most basic level of the standard. So does a form that marks errors only by turning the border red, and a line chart whose series are identified purely by a colour legend.
Fixing it is cheap: pair hue with a second, redundant channel. An icon and the word "Error" alongside the red. Dash patterns or direct labels on chart lines rather than a legend. Shape or position for state, not just fill. There is also a useful structural habit — separate the entries in a palette by luminance as well as by hue, because two colours with similar relative luminance and different hue can be nearly indistinguishable to a deuteranope. Convert the finished palette to greyscale as a check: any swatches that merge were relying on hue alone, and they will merge for real users too.
Related guides
Tutorials and guides to get more from this tool
Color Palette Guide: Create Accessible Designs 2025
How to create stunning color schemes that are also accessible to users with visual impairments.
Lorem Ipsum Explained: Why Designers Use It (2025)
2,000 years old and still relevant! Discover why every designer uses Lorem Ipsum. The fascinating history behind placeholder text in 2025.
Regex Cheat Sheet: Patterns That Hold Up in Production
A practical regex reference with tested patterns for IDs, dates, URLs and logs, plus the mistakes that cause bugs and catastrophic backtracking.
ThenCatch is a free developer toolkit. Learn more about us.