Figma rgba(0,0,0,0.5) Broke Prod CSS — HEX8 Fix
Designer drops rgba(99, 102, 241, 0.08) in Figma comments. You paste into Tailwind config. Production overlay looks wrong on Safari — too dark on mobile, invisible on desktop. r/webdev argues about hex8 vs opacity-50 for three days while PM asks “can’t you just match Figma?”
- 6-digit hex drops alpha silently —
#6366F1is fully opaque. Your 8% overlay becomes a solid purple block. - Parent
opacity:+ rgba child — Alpha multiplies.opacity: 0.5on a parent makes a child withrgba(..., 0.5)effectively 25% visible. - Figma export ≠ browser render — Different color profiles, subpixel rounding, and blend modes affect perception.
- “Just use Tailwind opacity utilities” — Fine until you need exact token values in a design system JSON file.
rgba → 8-digit hex reference
Alpha hex = round(alpha × 255).toString(16):
| rgba | hex8 | Notes |
|---|---|---|
| rgba(0,0,0,0.5) | #00000080 | 0.5 × 255 ≈ 128 = 0x80 |
| rgba(99,102,241,0.08) | #6366F114 | 0.08 × 255 ≈ 20 = 0x14 |
| rgba(255,255,255,0) | #FFFFFF00 | Fully transparent white |
Modern CSS accepts #RRGGBBAA in background, border-color, etc. Shorter than rgba() in token files:
:root {
--overlay-scrim: #00000080;
--brand-tint: #6366F114;
}
The double-alpha trap
<!-- Bad: stacked alpha -->
<div class="opacity-50">
<div style="background: rgba(0,0,0,0.5)">...</div>
</div>
Fix: put alpha only on the color, not the parent:
.scrim {
background: rgba(0, 0, 0, 0.5); /* one alpha source */
}
Or use hex8 in tokens so designers and devs share one value.
Figma → code handoff workflow
- Copy rgba from Figma inspect panel.
- Convert both directions in rgba-hex tool — rgba → hex8 → rgba to catch rounding.
- Preview swatch on white and #111 backgrounds — low-alpha grays lie on one background only.
- Add token to
tokens.cssor Tailwindextend.colors— document in PR. - Screenshot prod vs Figma in review — pixel diff optional, side-by-side mandatory.
Tailwind mapping example
Figma: rgba(99, 102, 241, 0.08)
// tailwind.config.js excerpt
colors: {
brand: {
tint: "#6366F114", // not bg-indigo-500/10 unless you verified match
},
}
bg-indigo-500/10 is close but not always identical — design systems often want exact hex8 from design file.
Figma-specific export traps
Figma shows 8-digit hex in the inspect panel when you enable alpha on a solid fill — but copied CSS from Dev Mode sometimes drops the alpha channel entirely. If your token file only has #6366F1 and the design overlay uses 10% indigo, the implemented hover state will look 10× stronger than spec.
Linear vs sRGB: Figma blends in sRGB by default. CSS color-mix(in srgb, …) (modern browsers) aligns better than guessing in spreadsheet converters. When handing off to Android/iOS, confirm whether native tokens expect 0–1 alpha or 0–255 — another silent mismatch.
Dark mode pairs: A scrim that works on #FFFFFF (rgba(0,0,0,0.4)) often fails on #0F172A — re-export at least two hex8 tokens per semantic color (overlay-light, overlay-dark) instead of one rgba copied from a single artboard.
When to use which format
| Format | Pros | Cons |
|---|---|---|
| rgba() | Readable alpha decimal | Longer strings |
| hex8 | Compact in tokens | Alpha less obvious |
| hsla() | Easy hue shifts | Same length as rgba |
opacity utility | Quick prototypes | Stacks badly |
Tool: convert locally
The rgba-hex tool converts rgba ↔ hex ↔ hex8 in your browser. Paste Figma values, copy CSS-ready output — nothing uploaded.
TL;DR
Don’t lose alpha when converting to hex. Avoid stacking parent opacity with rgba children. Convert with hex8 for tokens, preview on light and dark, then ship.