Skip to content
Tech News
← Back to articles

Too Much Color

read original get Colorful LED Strip Lights → more articles
Why This Matters

This article highlights the importance of optimizing color precision in CSS to reduce file size without sacrificing visual fidelity. For developers and the tech industry, it emphasizes that limiting decimal places in color values can lead to more efficient code, especially in minification processes, ultimately improving website performance and load times.

Key Takeaways

I've been working a lot on colours (or "color") in CSS, for csskit's minifier. This gives me the unfortunate burden of now having Opinions™ about colours. I also built a minifier test suite in the hopes that the ecosystem can get smarter. The minifier tests are not a vanity project: csskit currently has the worst pass rate and fails in some rather bad ways.

During this work, trying to minify oklch colours, I wondered "just how precise is precise enough?". Is a color like oklch(0.659432 0.304219 234.75238) needlessly precise? Spoiler alert: yes. I contend that you almost never need more than 3 decimal places. For oklch and oklab that's a safe ceiling, and for their less-than-ok variants (lab & lch) you can get away with even less. Writing more is just wasting bytes.

So here's the TL;DR:

When writing colors: 3dp is enough. If your colour picker hands you oklch(0.659432 0.304219 234.75238) , round it to oklch(.659 .304 234.752) and move on. No human can see the difference, and the maths hold up even if you're chaining colours through color-mix() or relative colour syntax. The exceptions to this are so edge case they're irrelevant. Or don't. I'm not your dad. Minifiers should handle this for you instead. Speaking of; minifiers (or try-hard developers) can be even more aggressive: lab() and lch() operate on much larger scales, so they only need 1dp. sRGB specific notations like rgb() & hsl() , or units like degrees can be 0dp. The details are below.

Does this matter? I mean, not really. A few extra digits is not going to harm anyone, but also if you're spending any significant time tweaking colour values by hand then anything beyond 2 or 3 decimal places is just a waste of time. If you're writing a minifier, like I am, then this stuff probably really matters to you.

The rest of this post is going to be me justifying that claim. If you trust me, you can stop reading now. If you don't, or if you want to hang around and play with some fun widgets, and hopefully learn something, then let's get into it!

How do you tell if two colours look the same?

First we need a way to measure whether two colours are actually different. Luckily the Europeans have been at it yet again. The International Commission on Illumination - CIE - inventors of the LAB colour space - made some fancy formula for figuring this out. Delta-E, shortened dE, or if you like fancy Unicode letters: ΔE. I'm not typing Delta-E all the time, and I am absolutely not copy pasting Δ symbols everywhere so it's dE from here on out.

You might see for example Delta-E CIE76 (often shortened to dE76) in older literature. Its updated sibling: CIE2000 (shortened as dE2000 or dE00) is the modern alternative that fixes issues with the first iteration. csskit uses dE00 to compute distance but calls it just delta_e because dE00 is a terrible name for a method.

At its core this formula gives you a single number: how far apart two colours look. 0.0 means identical, 100.0 means you're comparing black and white. The magic number to remember is the "Just Noticeable Difference" (JND). For dE00, JND is around 2.0. Below that, people struggle to tell two colours apart. Below 1.0, basically no one can. So anything under 2.0 is "close enough" and anything under 1.0 is "you're kidding yourself."

... continue reading