Hacker News new | past | comments | ask | show | jobs | submit login

Beautiful palette!

CSS recently has been adding way more color features, here's the palette represented in oklch:

    #817 → oklch(0.44 0.1815   335.38)
    #a35 → oklch(0.51 0.1559     7.49)
    #c66 → oklch(0.63 0.1298    21.44)
    #e94 → oklch(0.75 0.1415    62.42)
    #ed0 → oklch(0.88 0.18646  103.9148)
    #9d5 → oklch(0.82 0.181    131.77)
    #4d8 → oklch(0.80 0.1757   154.39)
    #2cb → oklch(0.76 0.1298   184.05)
    #0bc → oklch(0.72 0.123861 206.321)
    #09c → oklch(0.64 0.129199 231.0549)
    #36b → oklch(0.52 0.1448   260.03)
    #639 → oklch(0.44 0.1603   303.37)
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.





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.

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


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.


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...


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.

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.


For purposes like graphic design or color grading it's usually more useful to first focus on lightness contrast, then pick hue and chroma afterward. Having uniform steps of ΔE is not really important, and using that as a primary criterion will usually make for worse choices. Color is multidimensional and trying to simplify it to a single distance function is substantially misleading for this context.

The main purpose of ΔE is specifying error tolerances for specified colors / measuring small differences between nearby colors, so that e.g. if you hire someone to paint a car or print a magazine you can check that their output matches expectation sufficiently. For colors that are significantly different ΔE isn't that helpful a practical tool.


> Our eyes are much more sensitive to Blue/Violet, and less sensitive to green.

Hm? It's the exact opposite. That's why the full-intensity RGB green looks much brighter than the full-intensity blue. To convert RGB to pure luminance (gray), you do something like 0.3 * R + 0.6 * G + 0.1 * B, meaning green contributes six times as much as blue.


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.


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.


Unfortunately in the CSS implementation of oklab Chroma takes priority over Lightness, so if you have high Chroma and Lightness at 100% that results in a color outside the RGB gamut, it will not give you white, but the lightest color with that Chroma. To me this is quite counterintuitive.

with my posh upper-crust wide color gamut eyes *big eyelashes flutter-winking*

> L is for lightness (0-100%), C is for chroma (0-0.5), H is for hue (0-360deg).

My programmer brain immediately jumped away in disgust.

I'm sure there's many good reasons for choosing those, but it seems to me it could have easily have been done with 3 percentages (0-100% for the 3 numbers). Way easier to work with programmatically.


Hue is a cyclic value, so it has to be in degrees

Chroma cap is dependent on Lightness and Hue, so it has to be unsized to preserve "equal delta leads to equal color distinction" concept

In color spaces you just don't have any math that can be done without following its structure

You may check https://oklch.com/ on how the color space looks like


> Hue is a cyclic value, so it has to be in degrees

There's nothing magical about the number 360. You can do cycles in the 0-1 range. You can even make trigonometry with that (no radians). See:

http://pico8wiki.com/index.php?title=Sin


It does, that's why the default way to enter should've been at least okHSL and okHSV https://bottosson.github.io/misc/colorpicker/

But the RGB defaults can't be easily reasoned about either, so this is still an improvement, so it's not worse


The beyond tellerrand conference had a pretty good talk on the different color models in CSS: https://www.youtube.com/watch?v=9UyJe22WH58

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”.


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.


Isn’t that largely just a matter of learning the hue wheel? And maybe chroma to apply saturation?

OKLCH really shines if you have to interpolate color between two colors (e.g. in space resulting in a gradient or in time as part of an animation) or you just want to change a color without makingnit darker or brighter.

If you interpolate between RGB colors you will get very weird grayish shades inbetween and the new color may be preceptually darker or brighter, which may be a problem (e.g. if it is text on a background). With OKLCH you define one color and as you rotate around the color wheel it stays the same preceptual brightness, which is incredibly cool.

This means before a designer would have to touch 3 values (RGB or HSV) to match the colors preceptually using their eyeballs, now there is only one value and it matched nearly perfectly as it is.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: