CSS Minifier

Two directions through the same tokeniser: minify strips what the parser does not need, beautify puts the structure back. Both leave string literals and url() contents byte-for-byte alone, because whitespace inside those is meaningful.

CSS Minifier and Beautifier — Strip a Stylesheet Down or Open It Back UpBuildFigure

What minifying does, and what it deliberately does not

Applied: comments removed (with an option to keep /*! … */ licence headers, which is the convention every minifier honours), whitespace collapsed and dropped around braces, colons, semicolons and combinators, the final semicolon in each block removed, 0.5rem shortened to .5rem, 1.0rem to 1rem, zero lengths reduced to bare 0, six-digit hex shortened to three where the pairs repeat, hex normalised to lowercase, and empty rule blocks deleted.

Not applied, on purpose: merging duplicate selectors, collapsing longhand into shorthand (margin: 0 0 0 0 into margin: 0), reordering declarations, adding or removing vendor prefixes, and dropping rules that appear unused. Every one of those can change the result. Shorthand resets properties the longhand left untouched, reordering changes which of two equal-specificity rules wins, and "unused" cannot be determined from a stylesheet alone. A tool that guesses wrong about the cascade produces a stylesheet that is smaller and subtly incorrect, which is the worst available outcome.

Strings and url() are lifted out first

Before any rewriting, quoted strings and url(...) bodies are replaced with placeholders and put back at the end. This matters more than it sounds. The whitespace in content: " " is the value. A data URI holds semicolons — url(data:image/svg+xml;base64,...) — and a naive semicolon rule would truncate it. Font names with spaces, attr() fallbacks and generated content all depend on their literal contents surviving intact.

One space that is not removed anywhere: the operators inside calc(). calc(100% - 20px) requires whitespace around the minus sign, because without it the parser reads -20px as a signed number and the expression becomes invalid. Plus has the same problem. The whitespace collapse leaves single spaces in place rather than removing them, which keeps calc valid.

Why some zeros keep their unit

A zero length is a zero length regardless of unit, so 0px, 0em and 0rem all become 0 safely. Three cases are excluded:

ValueKept asReason
0%0%flex-basis and background-position treat a bare 0 differently from 0%
0s, 0msunchangedTime values require a unit; a bare 0 is invalid in a transition or animation
0deg, 0turnunchangedAngles require a unit in most functions, transforms included

These are exactly the cases where an over-eager minifier breaks a page in a way nobody notices until an animation stops firing.

Going the other way

Beautify re-indents a minified stylesheet one declaration per line, splits comma-separated selector lists onto separate lines, and adds a level of indentation inside @media, @supports and @keyframes. It is for reading a stylesheet you did not write, or checking what a build step actually emitted.

What it cannot do is undo minification. Comments that were stripped are gone, the original property ordering within a block is whatever the minifier left, and any name shortening a real build pipeline performed is not reversible. The working practice this implies is the ordinary one: keep the readable source under version control, generate the minified file as a build artifact, and never edit the artifact. If the only copy of a stylesheet you have is minified, beautify gives you something maintainable, but you have already lost the author's comments and you should say so in the commit message.

Questions people ask

How much does minifying actually save on a live site?

Less than the percentage shown here, because your server is almost certainly compressing the response already. Whitespace and comments are highly repetitive, which is precisely what gzip and brotli eliminate. Real-world measurements usually land in the 2-8% range after compression on a stylesheet that was already reasonably written. It is still worth doing in a build pipeline where it costs nothing, but it is not where a slow page gets fixed.

Does it handle SCSS or Less?

Partly, and not reliably. Nested rules and variable declarations happen to survive because they look structurally like CSS, but mixins, functions, control directives and interpolation are preprocessor syntax that this tokeniser knows nothing about. Run it on the compiled output instead — that is the file that ships anyway.

My layout broke after minifying.

Check the brace balance warning first; unbalanced input is the usual cause and the tool flags it. After that, look for a declaration missing its semicolon in the source, which is legal only on the last declaration in a block and breaks the next one when whitespace disappears. Diff the minified output against the original in a viewer that ignores whitespace, and the offending rule usually stands out.

Can I minify JavaScript with this?

No, and trying will corrupt the file. JavaScript has automatic semicolon insertion, regex literals that look like division, and template strings, none of which these rules understand. Use esbuild, terser or swc, all of which parse the language properly.

Related