Palette to CSS variables
This turns a pasted color palette into CSS custom properties, SCSS variables or a JSON token file. It also carries each color's contrast ratio into the output as a comment, so the file that lands in your codebase records which pairs were checked and which ones failed. All three formats, free, no account.
Your palette
- Requests
- · from Resource Timing
- Script
- · KB of a 100 KB budget
Why the contrast notes are the point
Exporting a palette to CSS variables is a find-and-replace with extra steps. Half a dozen tools do it and it takes four minutes by hand. That is not what this page is for.
The useful part is what the file remembers. A token file that arrives as eight hex
values tells the next developer nothing about which combinations are safe, so they
pick two that look nice and ship a 2.8:1 label. A token file that arrives with
/* on paper 5.12:1 AA, on ink 3.19:1 Fail */ next to each color answers
the question at the moment it gets asked, which is while somebody is writing the CSS,
not during an audit six months later.
The notes compare each color against the lightest and darkest colors in the palette, because that is what a palette actually gets used as: something dark for text on something light, and the reverse. For every pair rather than the two extremes, use the contrast grid.
Naming
Names become the variable names, lowercased with anything that is not a letter or a
digit turned into a hyphen. "accent deep" becomes --bnv-accent-deep.
Two different colors that slug to the same name are a collision, not a duplicate.
The first keeps the name; later ones get a numeric suffix such as
--bnv-brand-red-2
and the status line names the collision so nothing is silently overwritten. Identical
hex and name on two lines still collapses to one entry, which is the correct
duplicate.
A name that starts with a digit or is only punctuation would produce a custom
property that does not parse, so those get a color- prefix rather than
being emitted broken. It is a small thing that turns a file which silently fails to
apply into one that works.
Worth saying because it is the most common regret in a design system: name colors for
what they are, not what they currently do. --brand-blue survives a
redesign. --button-color becomes a lie the first time a button changes.
Three formats, one paste
CSS custom properties are the default because they are the only one that works at run time, which is what you want for a theme switch or dark mode. SCSS variables are compile time and cannot be swapped in the browser, but they are still what a lot of existing codebases are built on.
The JSON output is a flat token file, which is the shape most design token pipelines accept as a starting point. It is deliberately simple rather than being any particular vendor's schema, because converting simple JSON to a specific format is easy and converting one vendor's format to another is not.
Questions
Does this upload my palette?
No. The conversion is string handling and it runs in your browser. Even the download button builds the file in the page rather than fetching it from anywhere. Once the page has loaded, you can turn off your wifi and it all still works.
What do the contrast notes compare against?
The lightest and the darkest color in the palette you pasted, at the 4.5:1 normal-text threshold. Those two are the ones nearly everything ends up sitting on. They are not every pair, and if you need every pair the grid is the tool for it.
Can I paste CSS I already have?
Yes. It splits on line breaks, commas and semicolons and picks the hex value out of
each chunk, so pasting an existing block of custom properties mostly works. It
reads hex only, so rgb() and hsl() values are skipped
rather than misread.
Why is there no dark mode block in the output?
Because a dark theme is a second palette, not a transformation of the first one. Tools that generate one by inverting lightness produce something that technically contrasts and looks wrong, since the colors that read as calm on white read as muddy on near-black. Build the dark palette deliberately and export it as its own set.
Related tools
Before exporting, check the whole set with the palette contrast grid, or a single pair with the contrast checker. Worth also running it through the color blindness simulator, since contrast and hue are separate problems and passing one says nothing about the other.