What gets smaller
The stylesheet is first parsed by Prettier, which doubles as a syntax check, and then compressed by csso. These are the changes you will see:
- Comments go, every one of them, including
/*! ... */“important” comments that some minifiers preserve for licence notices. If your licence requires the notice to ship with the file, add it back at build time. - Whitespace around selectors, braces, colons, commas and inside functions disappears:
repeat( 3 , 1fr )becomesrepeat(3,1fr), and the last semicolon in each block is dropped. - Colours take their shortest form:
#FFFFFFbecomes#fff. - Numbers and units are trimmed:
0pxbecomes0,0.30sbecomes.3s. - Keywords with shorter equivalents are replaced, such as
font-weight: boldturning into700. - Quotes inside
url("base.css")are removed when the URL does not need them.
Strings are not touched, so content: " two spaces " keeps its spacing, and custom properties like --brand keep their values exactly.
Why rules are never merged or reordered
csso can also restructure a stylesheet: merge rules with identical declarations, move declarations between rules and drop ones it considers overridden. That can save more bytes, but it depends on assumptions about the cascade and about which elements match several selectors, and when an assumption is wrong a button changes colour in production with nothing in the diff to explain why. This tool runs csso with restructuring switched off. Two rules such as .a{color:red} and .b{color:red} stay two rules, a selector repeated later in the file stays where it is, and shorthand like gap: 16px 16px is left as written. What comes out applies the same styles, in the same order, as what went in.
On a commented, indented stylesheet the saving is still substantial: the first example below drops from 255 to 165 bytes, about 35%. Real-world framework CSS with long comment headers often shrinks by half.
Using the minifier
Paste CSS or open a .css file. The page starts in minify mode; Ctrl/Cmd+Shift+M switches to the formatted view and back, which is handy for reading a minified file from a CDN. CSS has no extra options here: Indent and line width only matter when formatting. Copy the output with Ctrl/Cmd+Shift+C. Minification happens in your browser, so unreleased designs and internal class names are not shared with anyone.
Feed it flat, compiled CSS. Nested rules, whether native CSS nesting or Sass and Less syntax, are not understood by the compressor: in .nav{padding:4px;.item{color:red}} the inner .item rule is dropped from the output without an error. Compile Sass and Less first, and flatten native nesting with your build tool (Lightning CSS or PostCSS) before minifying here.
Broken CSS is caught first
Because Prettier must parse the input before csso runs, an unclosed block, a declaration without a colon or a stray closing brace stops the process with a CssSyntaxError and its position. Browsers are forgiving about such mistakes and simply skip what they cannot read, which is how a missing brace silently disables every rule after it. Getting an error here is the cheaper outcome.
Examples
Theme stylesheet with comments
Both comments are dropped, 0px becomes 0, bold becomes 700 and #FFFFFF becomes #fff, while the custom property is untouched.
/*! theme v2.1 | MIT */
:root {
--brand: #2563eb;
}
/* buttons */
.btn {
padding: 0px 16px;
font-weight: bold;
color: #FFFFFF;
background: var(--brand);
}
.btn:hover { background: #1d4ed8; }
@media (max-width: 768px) {
.btn { width: 100%; }
}
:root{--brand:#2563eb}.btn{padding:0 16px;font-weight:700;color:#fff;background:var(--brand)}.btn:hover{background:#1d4ed8}@media (max-width:768px){.btn{width:100%}}Repeated selectors stay in order
All three .card rules survive in their original positions, so the later margin still overrides the earlier one.
.card { margin: 0 auto; }
.card { padding: 8px; }
.title { color: red; }
.card { margin: 0; }
.card{margin:0 auto}.card{padding:8px}.title{color:red}.card{margin:0}Grid layout with an import
Spaces inside repeat() and before !important are removed and the import URL loses its quotes; the gap shorthand is not rewritten.
@import url("base.css");
.grid { display: grid; grid-template-columns: repeat( 3 , 1fr ); gap: 16px 16px; }
.hidden { display: none !important; }
@import url(base.css);.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px 16px}.hidden{display:none!important}Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
CssSyntaxError: Unclosed blockExplained | A rule or @media block opens with { but never closes, often because a closing brace was deleted by accident. | Add the missing } at the end of the block. The position given is where the unclosed block starts. |
CssSyntaxError: Unknown word color | A declaration is missing its colon, as in color red, so the parser cannot tell property from value. | Write the declaration as property: value;. |
CssSyntaxError: Unexpected } | There is one closing brace too many, typically left behind after removing a nested block. | Delete the extra } at the reported column. |
Frequently asked questions
Is it safe to minify CSS?
With this tool, yes: rules are never merged, moved or removed, so the cascade behaves exactly as before. Only comments, whitespace and longer spellings of identical values are changed.
Does the CSS minifier keep licence comments?
No, all comments are removed, including /*! … */ ones. If a licence requires the notice, prepend it to the minified file in your build.
Can I minify SCSS or Less?
Compile them to CSS first. Sass and Less nesting is not flattened here, and nested rules would be missing from the minified output.
How do I unminify CSS from a website?
Paste it and switch to Beautify with Ctrl/Cmd+Shift+M, or use the CSS formatter. Comments removed by the original minifier cannot be recovered.