CSS Token Extractor
Pulls colours, spacings, radii and fonts out of a stylesheet and proposes a custom-property set.
Reads a stylesheet, counts every colour, length, radius, font and shadow in it, and proposes a `--variable` for each one, ordered by how often it is used. It can then rewrite the stylesheet to use them. It is a declaration scanner built on the CSS formatter’s tokenizer, not a full parser and not a linter — it tells you what values are in the file, which is the part that is tedious to do by hand.
CSS in
Drop a .css file
Read in this tab only.
Proposed tokens
Prepended, as in --app-color-1.
Declarations
29
Colours
11
Spacing values
5
Radii
3
Fonts
1
Variables already there
1
Colours 11
- #6366f1×2
- #fff×2
- #1f2937×1
- rgba(0,0,0,.06)×1
- rgba(0,0,0,.08)×1
- #111827×1
- #4b5563×1
- #4f46e5×1
- #eef2ff×1
- #4338ca×1
- #e5e7eb×1
Spacing 5
- 4px×1
- 8px×3
- 16px×4
- 24px×3
- 32px×1
Radii 3
- 8px×1
- 12px×1
- 999px×1
Font sizes 3
- 12px×1
- 14px×2
- 20px×1
Line heights 1
- 1.6×1
Fonts 1
- "Pretendard", system-ui, sans-serif×1
Shadows 2
- 0 1px 2px rgba(0,0,0,.06)×1
- 0 8px 24px rgba(0,0,0,.08)×1
How it reads the file
- · Read with the CSS formatter’s tokenizer, so a
url()or a#fffinside a string is not counted as a colour, andcalc()is left whole. - · Colours are normalised to hex, so #FFF, white and rgb(255 255 255) merge into one entry with a count. Names are numbered by how often each is used, so --color-1 is usually the brand or body colour — rename them.
- · Spacing comes only from margin, padding, gap and the inset properties, and radii only from border-radius, numbered by size. Width and height are left out: they are dimensions, not rhythm.
- · The JSON is the W3C Design Tokens (DTCG) draft shape, with $type and $value. "CSS rewritten with var()" replaces only exact value matches and leaves every other character alone.
To build a scale from a colour you pulled out, the tint and shade generator does that; for dark mode, the dark mode palette.
How to use it
Paste the stylesheet, or drop the file
One file at a time. The example that loads first is there to show the shape of the output before you go and find your own CSS.
Read the counts before the tokens
Forty colours in a file that should have twelve is the finding. The grouped lists below show each value with the number of times it appears, so the ones worth naming are at the top and the one-offs — which are usually mistakes or dead rules — are at the bottom.
Set a prefix if the project needs one
Empty gives `--color-1`; typing `app` gives `--app-color-1`. Either way the numbers are the usage ranking, not a meaning, so rename them once you know what each value is for.
Take the variables, the JSON, or the rewritten file
The CSS output is a `:root` block to paste at the top. The JSON is the W3C Design Tokens draft shape, for a build step or a design tool. The rewrite is the original stylesheet with exact value matches swapped for `var()` and nothing else touched — read the diff before you commit it.
Common questions
Is the rewritten CSS safe to ship as it is?
Read the diff first. The substitution is textual and exact-match only, so it will not break a value it does not recognise, but it also cannot know that two identical greys mean two different things — a border colour and a disabled label that happen to share a hex will get the same variable, and later someone changes one of them. Naming the tokens properly is the step that catches this, and it is a human one.
Why are width and height missing from the spacing list?
Deliberately. Spacing is a rhythm — margins, padding, gaps, insets — and a design system tokenises it. Widths and heights are dimensions: a 240px sidebar and a 44px tap target are not two points on the same scale, and putting them in the list buries the values that are.
Does it handle SCSS, Less, or CSS-in-JS?
Only plain CSS reliably. The tokenizer will get through a lot of SCSS, but nesting, `@mixin` bodies and interpolated values are not resolved, so the counts drift. Compile it first and scan the output — that is also the file the browser actually sees.
It found a colour inside a URL. Did it?
No — that case is handled. The scan runs on the CSS formatter’s tokenizer, so a `#fff` inside a `url()` or a string is a string, and `calc()` is left whole rather than being pulled apart into lengths. Those are the two places a regular expression gets this wrong.
Feed it from
CSS Beautifier & Minifier
Formats or minifies CSS without reordering anything, preserving the token stream exactly.
Palette Generator
Builds a harmonious palette from a base colour using complementary, triadic and analogous rules.
Dark Mode Palette
Builds a 50–950 ramp from one colour and mirrors it into a dark one, so each token pair keeps its contrast.
Nearest Tailwind Colour
Finds the closest Tailwind palette entry to any colour and shows the perceptual distance.
Next
These accept what this tool produces, so the result can go straight in.
Tint & Shade Scale
Generates a 50–950 lightness scale from one colour with perceptually even steps, ready as design tokens.
CSS Beautifier & Minifier
Formats or minifies CSS without reordering anything, preserving the token stream exactly.
Dark Mode Palette
Builds a 50–950 ramp from one colour and mirrors it into a dark one, so each token pair keeps its contrast.
Palette Generator
Builds a harmonious palette from a base colour using complementary, triadic and analogous rules.
Colour Format Converter
Converts a colour between HEX, RGB, HSL, HWB, LAB, LCH and OKLCH and names the nearest known colour.
Colour Picker
Picks a colour on an OKLCH field, with a screen eyedropper or from an uploaded image, and copies it in any notation.