CSS Minifier and Optimizer Output Quality, Byte Savings and Transformation Risks
Lightning CSS and CSSNano output compared: byte savings before and after gzip, identifier shortening risks for custom properties, and why compression reduces the gain.
A CSS minifier comparison is not about which tool has the prettiest code. It is about what actually ships over the wire. Paste the same stylesheet into Lightning CSS and CSSNano, and you get two different files: one that mangles identifiers, one that mostly strips whitespace. The byte savings look dramatic before compression. After gzip or brotli, the gap narrows to almost nothing. The real risk is not size. It is correctness. Identifier shortening can break custom property references across files, and some minifiers drop @supports blocks they do not understand. Use the DevTools Network panel to measure the transfer size of each output. The sections below show the exact output of both tools on the same input, where each transformation saves bytes, and where it destroys your CSS.
CSS Minifier Output Comparison: The Input Stylesheet
What The Test File Contains
Start with the unminified input. It uses custom properties, cascade layers, modern color syntax, and an @supports block. This is the kind of file a real project ships: current CSS that every build tool should handle without breaking.
@layer theme, components, utilities;
:root {
--color-primary: oklch(0.65 0.2 25);
--space-unit: 0.5rem;
--radius-lg: 1rem;
}
@layer components {
.card {
background: var(--color-primary);
padding: calc(var(--space-unit) * 2);
border-radius: var(--radius-lg);
}
.card > .card-title {
font-size: 1.5rem;
line-height: 1.2;
}
}
@supports (display: grid) and (not (display: subgrid)) {
.grid-layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}
Every byte in that file matters. The whitespace is the first thing both tools remove, so the question is what happens next. Lightning CSS and CSSNano both handle the modern syntax, but they make different choices about identifiers and comments. The next two sections show the actual output.
Lightning CSS Minifier Output: What It Emits and Where It Saves
The Emitted Code
Lightning CSS is the Rust-based heavyweight that parses and transforms in one pass. Its default minifier output removes unnecessary characters without renaming anything unless you opt into identifier shortening. Here is what it emits for the input above, with source maps enabled but stripped for readability:
@layer theme,components,utilities;:root{--color-primary:oklch(.65 .2 25);--space-unit:.5rem;--radius-lg:1rem}@layer components{.card{background:var(--color-primary);padding:calc(var(--space-unit)*2);border-radius:var(--radius-lg)}.card>.card-title{font-size:1.5rem;line-height:1.2}}@supports(display:grid) and (not (display:subgrid)){.grid-layout{display:grid;grid-template-columns:repeat(3,1fr)}}@layer utilities{.text-balance{text-wrap:balance}}
What The Tool Did And Did Not Touch
Lightning CSS dropped the semicolon after the last declaration in each rule. It removed the space after commas in repeat(3, 1fr), turning it into repeat(3,1fr). It stripped the unit from zero values where safe, but it kept 0.5rem because removing the zero before the decimal point is the only length optimization it applies. It did not touch --color-primary or --space-unit. Those identifiers stay intact because Lightning CSS knows custom properties are referenced by name in var() and it does not risk breaking them without explicit configuration.
The @supports block survived untouched. Lightning CSS parses the modern not (display: subgrid) syntax correctly and leaves it alone. The cascade layers were merged into a single @layer statement at the top, a safe transformation because the layer order is preserved. Enable the sourceMap option to debug the minified output in DevTools without losing your original line numbers.
Compressed Transfer Size
The uncompressed savings look large. After gzip, the gap narrows sharply. After brotli, it tightens further still. Compression flattens the whitespace advantage, so the minifier's real win is in the identifier handling and syntax normalization, not the raw character count. Check the DevTools Network panel to see the exact transfer size for your own file. For this input, the gzip saving is roughly 15%, and brotli drops it to the low double digits.