Gamma and Linear Color, Explained for Designers
Why "50% gray" is not actually halfway between black and white, and why your gradients sometimes look muddy. The shortest possible primer on gamma.
Pick a fresh canvas. Paint half of it #000000 and half of it #ffffff. Now ask: what HEX value should the strip between them be to look like a perceptual midpoint? Most designers say #808080. The honest answer is closer to #bcbcbc. The gap between intuition and reality is gamma.
What gamma actually is
Human vision is non-linear: we are far more sensitive to small differences in dark tones than in bright ones. A 1% change in dark gray reads as a noticeable step; a 1% change in near-white is invisible. To use bits efficiently, every consumer image format encodes color with a gamma curve - a non-linear bend that gives more bit precision to dark values.
sRGB uses a curve that is approximately gamma 2.2. So #808080 stored on disk decodes to a linear-light value of about 22%, not 50%. Hence: middle-gray-on-disk looks dark.
Why this breaks gradients
When the browser interpolates a gradient from #ff0000 to #00ff00 in sRGB, it linearly averages the encoded values - even though those values are non-linear. The midpoint becomes a dim, muddy olive instead of a clean yellow. This is the classic "ugly gradient middle".
The fix
Interpolate in a linear color space. CSS Color 4 lets you opt in:
background: linear-gradient(in oklch, #ff0000, #00ff00);
OKLCH is roughly perceptually uniform, so the midpoint feels right. in srgb-linear, in lab and in lch also work, with different visual flavors.
Where else gamma matters
- Compositing transparent layers. Photoshop's "Better" blending vs straight blending is gamma vs linear.
- Image downscaling. Naive downscaling in sRGB darkens highlights. Most modern engines convert to linear, downscale, convert back.
- Anti-aliased text. Subpixel rendering assumes a linear blend. Wrong gamma = blurry edges.
- Color picker midpoints. If your "lighten by 50%" feels like 20%, you are reading a gamma-encoded value.
The one-line takeaway
Color values you store, share or paste are gamma-encoded. Color values that get blended, averaged or composited correctly are linear. Use in oklch on every gradient that crosses hues, and your eyes will thank you.
Compare a sRGB-interpolated gradient against an OKLCH one, side by side, in our Gradient Maker.