The 12-bit rainbow palette
53 comments
·April 28, 2025jasonthorsness
nonethewiser
Whats the deal with oklch? My naive reaction was a that it sucks to define colors in a way you can’t easily reason about or need and external tool to make.
zeroq
Short answer - RGB is really convenient for lighting up sub pixels on your LCD screen, but it's utterly terrible at conveying information about relation between colors. HSL is a clever hack to quickly answer which color is slightly dimmer or brighter than this color, but again, it's quite terrible at conveying information about difference between colors.
I encourage you to think about two random colors and imagining a gradient between them and then drawing said gradient in RGB and HSL color spaces. In both cases it will be wildly different from what you'd expect or could create with two blobs of oil paint on canvas.
Long answer - unfortunatelly it's quite hard to convey why we need a better color space in twitter-space but this video (while 40m long it's quite condensed) is an excellent explainer: https://www.youtube.com/watch?v=gnUYoQ1pwes
lemonberry
Previous discussion and an excellent link here: https://news.ycombinator.com/item?id=43073819
OKLCH is really easy to work with. Once you have your palette it's easy to get correct shades and hues by tweaking some values. This works great with CSS custom properties.
ChadNauseam
oklch and oklab are much easier to reason about than alternatives. For oklch, The first parameter is the lightness, the second is the chroma (essentially its saturation), and the 3rd is the hue. I find it very easy to tweak colors by making them brighter or more saturated. Unlike lch, such changes in oklch have regular effects on how the color will be percieved.
This page has more information: https://evilmartians.com/chronicles/oklch-in-css-why-quit-rg...
MrLeap
This is the first I've heard of oklch. Here's the perspective of somebody who writes a lot of shaders: It looks similar to Hue/saturation/value encoding, which as tons of uses, but with saturation replaced with "chroma" where it seems to nonlinearly adjust saturation probably based on some perceptual study that makes it extra spicy and high science.
snibsnib
I used to work in a paint lab. You are correct, oklch seems to be based off CIELCh.
Our eyes are much more sensitive to Blue/Violet, and less sensitive to green. There's a bunch of maths behind the perceived responses of our eyes.
If you're interested you can calculate perceived differences in the LCh colorspace using something like CIEDE2000.(https://en.wikipedia.org/wiki/Color_difference#CIEDE2000)
A Rainbow with equal DE between colors would probably look better than this one with equal DL.
jcranmer
There are three main models to numerically model a color space.
There is an additive color mixing model, which is basically your standard RGB model, where you basically control how bright each of the red, green, and blue lamps shining at a point. There is a complementary subtractive color mixing model, which is controlling the amount of pigments you drop onto a substrate (CMYK is what you'll see used in computers these days). Then there's a third model, where you measure it according to brightness, colorfulness, and then the actual hue it is--there's a lot more variants in this model, basically any colorspace you don't recognize is this kind of model.
If you visualize colors existing in an RGB cube, you have 8 colors at the vertices: black and white are at opposite ends of a diagonal, and the other 6 are two sets of nonadjacent vertices: red, green, and blue in one set, and cyan, magenta, and yellow in the other set. Given such a cube, you should be able to easily see that RGB is using one of those sets as its basis set, whereas CMYK is using the other set as its basis set. The third set of models is built by tilting the cube such that the black-white diagonal is now the vertical line (one of the components), and then distance from this line becomes another component, and then the angle around the line is the final component--it's a cylindrical coordinate space in 3D space, not a Cartesian space.
Some models, like CIELAB or Oklab, use the third model but retain a Cartesian coordinate system, the last two values being called something generic like 'a' and 'b'. Oklch is the same as Oklab, but expressed as cylindrical coordinates, because chroma (colorfulness aka distance from the pure light line) and hue (aka the dominant color of the light) is more convenient for people to work with than a Cartesian system.
diegof79
The deal with Oklch is that hsl/hsb don’t do a good lightness mapping regarding color perception, but Oklch does. So, if you transform your RGB to lch and move the “l” value, you can easily get a nicer color palette. Also, you can tell the lightness of two colors by looking at the “l” value; that’s not true for hsl/hsb. That’s useful if you want lightness contrast or different hues with a similar lightness.
Other than that, I agree that “chroma” is hard to reason about. But, at least it is easier to reason than the “a”/“b” parameters in “lab”.
striking
L is for lightness (0-100%), C is for chroma (0-0.5), H is for hue (0-360deg).
Lightness dictates how white or black a color is, chroma dictates how saturated it is, and hue is which angle on the color wheel it occupies. Varying these one at a time lets you intuitively pick colors that are close to one another in the space of human perception. And CIE Lab colors are especially nice because they cover more than the sRGB gamut that we're all used to defining with HSL or RGB, so you can really make the most of your fancy wide color gamut monitor.
WhitneyLand
The win is working with lightness and contrast. For example, once you have a palette, making it a bit lighter is easy.
The loss is no longer having any intuition about what a color is just by seeing the numbers.
masklinn
Isn’t that largely just a matter of learning the hue wheel? And maybe chroma to apply saturation?
zeroq
This is nice, and works really nice for her use case!
Two things to note when thinking about color schemes:
(1) dr. Cynthia Brewer spent way too much time developing the color scheme for maps with information and similar inforgraphics. I can't find the document at this time, but was a lecture long explanation about how she got them.
(2) designers often use "sacred geometry" bullshit like "golden ratio", PI, Phi, and such to explain their thought process. The most common way to create a color palette is to use opposite colors, "triads" and "tetrads". All of this is based on color wheel in HSL/HSV. Which is almost as bad at describing relation between colors as RGB. [2]
PS. my pet peeve for a long time was trying to understand why most color quantization algorithms were relying on finding the distance between RGB colors in 3D space (by mapping RGB components to XYZ coordinates) while it's obviously a terrible way to reason about color relationship.
PPS. a random dude with a similar interest but way more dedication (re)disovered a work by Kubelka and Munk from 1931 describing an algorithm how to properly mix colors and based on that created an incredible graphics program that allows you to paint just like in real life - with oils and watercolors on canvas! [3]
[1] https://colorbrewer2.org/ [2] https://www.youtube.com/watch?v=gnUYoQ1pwes [3] https://www.escapemotions.com/products/rebelle/about
barrkel
My usual problem with these palettes from color blindness. The two greens are almost identical for the most common type. They don't have good contrast if they're e.g. used for lines in a chart.
eyegor
https://cran.r-project.org/web/packages/khroma/vignettes/tol...
The tol palettes are the best looking colorblind friendly palettes to me. Most of the others get complaints from non colorblind users about looking bad/desaturated.
levocardia
The viridis package is great for this too! https://cran.r-project.org/web/packages/viridis/vignettes/in...
The top comment color palette also reminds me a lot of the viridis "turbo" palette, which is a more perceptually uniform on MATLAB's notoriously bad "jet" palette
bee_rider
I tried to get a palette that would work for colorblind people, but I only made it up to 3-4 colors IIRC. I needed to plot more lines… so I ended up using shapes. My plot could be more beautiful without them, but at least everybody can read it. :shrug:
colechristensen
From not-color-blindness, there are more than a few pairs which would still be bad choices for lines on a chart.
whall6
Why is the far left and far right nearly the same color? If you’re showing a gradient the max and min would be nearly indistinguishable.
saretup
That would be a waste of a data point. Consider joining the colors in a circular shape.
BugsJustFindMe
> chosen with consideration for how we perceive luminance, chroma, and hue
Needs more consideration. The colors are not equally different.
p1necone
I think the only way to fix that would be to darken the yellow to the point where it's not really perceived as yellow anymore though - more like a muddy mustard.
edit: op originally specifically referred to yellow.
01HNNWZ0MV43FF
Yeah, the purples look very close on my screen
sho_hn
It looks quite fantastic on my fairly new OLED screen, and the colors are pleasingly differentiated here.
Obviously designing for bad screens and/or eyes are both very important considerations, though.
NelsonMinar
The 12 bit constraint is a fun one although a little artificial. But picking 12 different colors with constant luminance is quite a challenge! ColorBrewer only goes to 9, and to my eyes more than 6 is very hard to make out. But these 12 are quite nice if you don't mind a little blurring, particularly folks with some form of colorblindness.
hedora
Technically, this is a 3.5849625 bit palette, though if you add black, white, transparent, and a reserved entry, it’d be 4 bit.
WatchDog
Right. A 12 bit palette would be 4096 colors.
turnsout
In this context, 12bit refers to the combined bit count of RGB (each 4bit)
WatchDog
In the context of the original post, or in the context of talking about color depth in general?
In the context of the original post, it seems like Kate is just talking about 12 total colors, it's not 12 bit in any logical sense.
In the context of color depth sure, 12-bit color[0] would be 4 bits per channel.
Dwedit
The problem with using 12-bit sRGB is that sRGB is not a linear colorspace. You're not taking 16 evenly spaced points in the full range of brightness, you're taking 16 points along the sRGB curve.
cdev_gl
Really cool project! I like the twelve color palette the author presents, and the grayscales, but I'd love to see more about the choice to use twelve bits to encode it. Presumably enough of the rest of the possibility space is needed to justify writing a custom encoding. Or maybe it was done because custom color encodings are cool, which they definitely are.
The palette is so pretty, I wonder how the whole LCH color space quantized down to 4096 colors looks. I find limited bitdepth color spaces fascinating to look at, there's so many choices about how to represent color they can look wildly different.
jjmarr
Why is 12 bits 4 characters? Shouldn't it be 3 hexadecimal digits (as shown on the website), since each digit is 4 bits?
saurik
3 hexadecimal digits and one # symbol is 4 characters.
shadowfacts
Four characters counting the pound sign.
tom_
It takes fewer keypresses to refer to it simply as #, which is worth doing as its name is locale dependent.
null
null
kazinator
By LCH, is she referring to this?
https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical...
I've not paid much attention to this aspect of CIELAB, but, oh, I see; if you go clockwise around the rectilinear representation you do get rainbow order.
mcdeltat
Must be because most other colour spaces are not very perceptually uniform. I initially thought a variety of HSL but that is definitely not uniform.
Beautiful palette!
CSS recently has been adding way more color features, here's the palette represented in oklch:
You can see the lightness and chroma moving within a narrow range as it sweeps the hue. These new color space functions make making palettes like this way easier.