zhihu wuDesigners 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.
CSS defines 8-digit hex as #RRGGBBAA — alpha last. Android, Flutter and Kotlin define it as #AARRGGBB — alpha first. So #80FF0000 is:
0x80, green 0xFF, blue 0x00, alpha 0x00 → completely invisible. Your UI element quietly disappears.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.
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.
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.