Three Hex Color Bugs That Survive Code Review

# webdev# css# javascript# design
Three Hex Color Bugs That Survive Code Reviewzhihu wu

Designers hand off hex strings. Developers paste them. And three times out of ten the string is fine...

Designers hand off hex strings. Developers paste them. And three times out of ten the string is fine and the render is still wrong — because a hex value is not a color, it's a set of numbers that each platform reads differently.

1. Eight digits, two different channel orders

CSS defines 8-digit hex as #RRGGBBAA — alpha last. Android, Flutter and Kotlin define it as #AARRGGBB — alpha first. So #80FF0000 is:

  • CSS: red 0x80, green 0xFF, blue 0x00, alpha 0x00 → completely invisible. Your UI element quietly disappears.
  • Android: alpha 0x80, red 0xFF, green 0x00, blue 0x00 → a 50% red overlay.

Same literal, opposite meaning, no error anywhere. Six-digit hex is safe because all three channels are present in the same order; the moment you add the fourth pair you have an ambiguous string. Hand off rgba(255, 0, 0, 0.5) or a 6-digit hex plus a separate opacity token instead.

2. Alpha is not a color (so don't pre-blend it)

Converting a translucent overlay into a solid hex "so it fits the palette" only works against one background:

  • rgba(0, 0, 0, 0.5) over #FFFFFF → #808080
  • rgba(0, 0, 0, 0.5) over #3366CC → #1A3366

Pre-blending bakes in the surface it happened to sit on. The same 50% black is mid-grey on a white card and dark navy on a blue hero. Keep alpha as alpha, or record which surface the hex was measured against.

3. Hex carries no color space

A hex code says nothing about gamut. The same #FF0000 is a different physical color on an sRGB laptop panel and a Display P3 phone — and a color you sample from a wide-gamut screenshot is P3 coordinates wearing an sRGB costume, which is why saturated colors read duller or hotter than the designer's file. CSS color(display-p3 …) exists precisely because 8-bit hex can't express what those screens can show.

None of these are exotic edge cases — they show up in handoff, in dark-mode overlays, and in "the color looks different on my machine". What they share is that the number is right and the format is wrong.

💡 When I'm chasing one of these, I use the CodeToolbox color picker to see the same color as HEX, RGB, HSL and oklch side by side — it's client-side, so I can paste in a value without uploading a screenshot anywhere.

Which one has bitten you? For me it's #2 — every translucent overlay we ever "simplified" into a hex eventually sat on a different background.