CSS Variable Generator
Generate CSS custom properties from any color — HEX, RGB channels, HSL channels — ready to paste into a :root block for modern design tokens, theming, and color-mix() workflows.
- Three output shapes: raw HEX, RGB channels, HSL channels
- HSL channel form unlocks `color-mix()`, opacity, and dark-mode swaps
- Copies as a paste-ready :root block
- Works for a single brand color or any palette swatch
Direct answer
var(--name). For colors, the trick is to store channel components (e.g. --brand: 220 80% 50%) rather than full color strings, so opacity and mixing work without re-parsing.CSS Variable Generator
#6366F1
CSS Variables
:root {
--brand: #6366F1;
--brand-rgb: 99 102 241;
--brand-hsl: 239 84% 67%;
}When this saves you time
Real workflows where css variable generator replaces tedious manual work or an in-app subscription tool.
One brand color, every shade
Swap lightness only
Pass color as prop
10% alpha for backgrounds
Fallback for legacy email clients
Sync with Figma variables
How it works
The methodology — every transformation documented so the output is reproducible.
Parse the input
HEX, RGB, or HSL — all normalized to a canonical color model. Invalid input is flagged inline.
Emit channel-only forms
Modern CSS treats `hsl(220 80% 50%)` and `rgb(255 0 0)` as space-separated channel triples. We emit just the channel string so it composes with opacity (`/`) and `color-mix()`.
Wrap in :root
Output is a ready-to-paste `:root { ... }` block. Drop into `globals.css` or any layer-0 stylesheet.
Reference anywhere
Use `color: hsl(var(--brand))` for full opacity; `color: hsl(var(--brand) / 50%)` for 50% alpha — no extra variable needed.
Worked examples
| Input | Result | Notes |
|---|---|---|
| #7A3DFF | --brand: 263 100% 62%; | HSL channel form. Use `hsl(var(--brand))` or `hsl(var(--brand) / 50%)`. |
| #C8102E | --red: 350 85% 41%; | Red-family channel. Lightness 41% gives strong contrast on white. |
| rgb(20 40 160) | --accent: 232 78% 35%; | Normalized to HSL channels. Original RGB form also emitted. |
| hsl(160 60% 45%) | --mint: 160 60% 45%; | Pass-through when input already HSL — useful for systematic palettes. |
Common mistakes to avoid
Storing full color strings
Mixing comma and space syntax
Naming by HEX, not by role
Forgetting dark-mode lightness
Frequently Asked Questions
Why channel-form variables won the design-token war
Until 2020 the default was --brand: #7A3DFF: one variable, one HEX. The pattern broke the moment you needed a 50% alpha background — you had to add --brand-50: rgba(122, 61, 255, 0.5) for every opacity step. Channel-form variables solve this by storing the components (263 100% 62%) and letting the CSS color function re-assemble them at use site: hsl(var(--brand) / 50%) gives 50% alpha; hsl(var(--brand) / 10%) gives 10% — no second variable.
color-mix() unlocks runtime palette generation
With channel variables in hand, color-mix() can generate tints and shades at runtime: color-mix(in oklch, var(--brand-hsl) 70%, white). That removes the need for a token per shade — your design system ships one variable per role and the browser interpolates the rest in a perceptually-uniform space (OKLCH or sRGB-linear, your choice).
Naming tokens by role, not by value
A token named --purple-600 describes a value. A token named --primary describes a role. The second survives a rebrand. The pattern most design systems converge on has two tiers:
- Reference tokens:
--color-purple-600— name follows value. - Semantic tokens:
--primary,--surface,--text-muted— name follows role, value points at a reference token.
Generate semantic tokens for everyday use; keep reference tokens as the immutable palette layer underneath.