Random Color Generator
Random colours drawn in HSL with the hues spread around the wheel, each one with its contrast against black and white, so the set is usable rather than mud.
Waiting for your browser
Colours are drawn from crypto.getRandomValues when the page loads, so
they are yours rather than the build's. Until then this is the
placeholder, #1e56ec.
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Three random bytes give you a uniform point in the RGB cube, and most of that cube is mud. The results cluster near the greys because that is where the volume is, half of them are too dark to put text on and too light to read against, and a set of six has no relationship to each other at all.
So the randomness here happens in HSL. The hue is free, the saturation and lightness stay inside a band you choose, and the hues are spread evenly around the wheel from a random starting point rather than drawn independently. That is what makes a set look like a family instead of a screenshot of a random number generator.
Every colour arrives with its contrast against black and against white, and the tool names which text colour to use.
How to use
- Pick a range: vivid, pastel, muted, dark, light, or custom.
- Choose how many colours and how much hue jitter you want.
- Copy the hex values or the custom property block.
Example
Five vivid colours, hues 72 degrees apart with a 12 degree wobble:
Mood vivid (saturation 70-100%, lightness 45-60%)
Hues 5 spread 72.0° apart, ±12°
#47c5e7 rgb(71 197 231) · oklch(76.8% 0.118 219.5)
white text 2.02:1, black text 10.41:1 — use black text, AAA
#920ee7 rgb(146 14 231) · oklch(53.3% 0.272 304.3)
white text 6.11:1, black text 3.44:1 — use white text, AA only
#c82351 rgb(200 35 81) · oklch(54.6% 0.198 11.9)
white text 5.50:1, black text 3.82:1 — use white text, AA only
#d4e529 rgb(212 229 41) · oklch(88.0% 0.191 115.2)
white text 1.40:1, black text 15.04:1 — use black text, AAA
#1edb56 rgb(30 219 86) · oklch(77.9% 0.225 147.0)
white text 1.85:1, black text 11.32:1 — use black text, AAA
Yours will differ: the colours are drawn when the page loads.
One fact worth taking away from that table: every colour carries either black or white text at the AA threshold, and that is arithmetic rather than luck. The ratio against white falls as a colour darkens and the ratio against black rises, and the two cross at 4.58:1. The better of them can never be below 4.5. The useful question is not whether a colour can hold text, it is which text, and whether it reaches 7:1 for AAA.
Pitfalls
Uniform random RGB is not a palette. It is not even a set of usable colours. The bands exist because the useful part of the space is a thin slice of it, and the “any” option is included so you can see what happens without them.
Independent random hues clump. Six uniform draws will usually put three colours in one quarter of the wheel and leave a gap opposite. Spreading the hues and randomising only the starting point gives you a set that covers the wheel, which is what a palette needs.
Equal lightness in HSL is not equal lightness to the eye. hsl(60 100% 50%) is
yellow and looks bright; hsl(240 100% 50%) is blue and looks nearly black. Both are
50 percent lightness. That is why the oklch value is printed too: in oklch the
lightness number means what it says across hues.
Contrast is against a background, not a property of a colour. The two ratios here are against black and white, which is the common case. If your background is a mid grey, neither figure applies, and the contrast checker on this site is the tool for it.
AA is a floor, not a target. 4.5:1 is the minimum for body copy, and copy set at exactly 4.5 is legible rather than comfortable. AAA is 7:1, and the tool says which colours reach it.
Random is a starting point. A generated set gives you somewhere to begin. A brand palette needs a decision about what the colours mean, which needs a person.
Compatibility
Randomness comes from crypto.getRandomValues, and the page recomputes on load, so
what you see is yours. At build time there is no randomness, so the default output says
it is waiting for your browser rather than baking a colour into a page every visitor
would see.
Contrast ratios are the WCAG 2 formula on relative luminance, which is the one that conformance is measured against. It has known weaknesses, particularly for dark backgrounds, and APCA is the proposed replacement in WCAG 3; until that lands, this is the number that counts.
Values are sRGB, which is what a hex code means. oklch is printed alongside because it
is the space to edit a colour in, and it is in every current browser: oklch() has
been supported since 2023, so you can paste those values straight into CSS.