Paste CSS to tidy it up, and see exactly what minifying saves
The CSS Formatter & Minifier turns the same stylesheet in two directions. Formatting (also called beautifying) takes a squashed line such as .card{margin:0;padding:16px}, puts one declaration on each line and indents it so a person can read it. Minifying goes the other way: it deletes comments, whitespace and line breaks that the browser never needs, so the file you ship is smaller. Either result has to paint the page exactly as the original did, and this tool is built around keeping that promise.
Stripping whitespace with a regular expression is the quick way to break a stylesheet, because it also removes the spaces around the minus in calc(100% - 2rem) and makes the value invalid. This tool reads the code the way the CSS specification describes it, as comments, strings, brackets and declarations, and only then writes it back out. That is how it can tell a space that is safe to delete from one that carries meaning. Below the result, the size map draws the source and the output as two bars on one scale, so you can see how much the rules, the @media blocks and the comments each take up and how much of that disappeared. The Findings panel points to errors by line number, for example a single stray } that makes the browser throw away the next rule.
When you need to format or minify
The shape a stylesheet should have while you edit it is not the shape the browser wants to download. Editing calls for spread-out code and delivery calls for short code. These are the situations where the tool helps.
- Reading a library's .min.css: if all you have is the minified file and you want to know where a button colour is set, expand it first. Paste it in Format mode and search the result box.
- Cleaning up styles copied from dev tools or another site: copied CSS often has mixed indentation or sits on one line. One pass makes the boundary between selectors and declarations obvious.
- Pasting into a custom CSS box in a site builder or theme editor: when the box is small or has a character limit, the minified version fits more easily. Keep the original somewhere else and paste only the minified copy.
- Hunting for styles that do not apply to part of a page: the cause is often a stray
}or an unclosed bracket in the rule just before. Findings shows the line and the selector that gets dropped. - Checking what minifying really buys you: the percentage saved in raw bytes is not the percentage saved over the wire with gzip. The gzip bar in the size map shows both side by side.
How to use it
- Paste your CSS into the input box on the left (above it on a narrow screen). You can also press Open file or drop a .css file onto the box. Files up to 5 MB open.
- Choose Format or Minify at the top. The result updates as you type.
- Format lets you pick the indent (2 spaces, 4 spaces or a tab), whether to keep comments and whether selectors are split at each comma. Minify lets you choose how comments are handled (keep /*! only, remove all, keep all) and whether hex colours are shortened.
- Select a segment of a bar in the size map to highlight that part in the result box. Select a line-number button under Findings to select that line in the input box.
- Use Copy result to put it on the clipboard or Save as file to download it. Minified output is saved with a .min.css ending.
What formatting changes
Formatting never reorders anything. It only places line breaks and spaces again. Each declaration goes on its own line with a single space after the colon and a semicolon at the end, and nested rules are indented one more level. One blank line separates blocks, and a comment that sat at the end of a declaration stays at the end of that declaration.
| Input | Formatted | Rule |
|---|---|---|
.a{color:red;margin:0} | .a { / color: red; / margin: 0; / } | One declaration per line, a space after the colon |
h1,h2>a{…} | h1, / h2 > a { | Top-level commas break the line; spaces around > + ~ |
rgba(0,0,0,.5) | rgba(0, 0, 0, .5) | A space after commas inside values |
@media (min-width:600px) | @media (min-width: 600px) | A space after the colon inside a condition |
color:red!important | color: red !important; | A space before !important |
.menu{&:hover{…}} | .menu { / &:hover { | Nested rules indent one more level |
--list: a,b | --list: a,b; | Custom properties (--) only get their spaces collapsed to one |
As the last row shows, a custom property that starts with -- does not get a space after its commas. The value of a custom property is stored exactly as written, and JavaScript's getPropertyValue() returns that same text, so a space added for looks could change what a script reads. Breaking selectors at commas can be turned off, and when it is, you get h1, h2 > a { on one line.
What minifying removes, and what it keeps on purpose
Minifying shortens the text only where the outcome is identical. Most whitespace can go, but some of it is part of the grammar, and removing it produces different code. The lower six rows of the table are places where other minifiers often break things, and this tool leaves them alone.
| What | When minifying | Why |
|---|---|---|
| Comments | Removed (comments starting with /*! are kept by default) | /*! is the convention for keeping a licence notice, and cssnano's comment cleanup keeps it by default too |
| Line breaks, indentation, spaces around { } : ; , | Removed | Whitespace that is not needed to separate tokens |
| Semicolon at the end of a block | Removed | The ; after the last declaration makes no difference either way |
#FFFFFF, #AABBCCDD | #fff, #abcd | A hex colour whose digits repeat in pairs is the same colour in 3 or 4 digit form (CSS Color 4 §5.2) |
Spaces around + and − in calc(100% - 2rem) | Kept | Whitespace on both sides of + and − is required (Values 4 §10.8). 100%-2rem is invalid |
The space in and ( and not ( | Kept | Without it, and( is read as a function (Media Queries 4 §3) |
The space in .card :hover | Kept | The space is the descendant combinator, and deleting it gives .card:hover, a different selector (Selectors 4 §14.1) |
The unit on 0px and 0% | Kept | In flex: 1 0px, dropping the unit makes the 0 read as a shrink factor (Flexbox §7.1), and a keyframe selector 0% only accepts a percentage (Animations 1 §3) |
Empty rules and empty @layer blocks | Kept | Layer order follows the first declaration (Cascade 5 §6.4.3), so even an empty @layer base {} sets the order |
Custom property values, strings and url() contents | Whitespace tidied only, text unchanged | A custom property's value is the text as written, and the contents of strings and URLs are data |
That is why a value like --brand: #C44A00 keeps its upper-case hex after minifying, while color: #FFFFFF on a normal property becomes #fff. The What changed list reports the comments removed with their bytes, the semicolons dropped, the colours shortened and the bytes saved by whitespace, each on its own line.
How much it saves: ratio and gzip transfer size
The bytes you save by minifying are not the bytes that cross the network. Most servers compress CSS again with gzip or brotli, and that kind of compression is very good at repeated patterns, so the indentation and line breaks you strip are already mostly squeezed out. The table below minifies this page's example and the published Bootstrap 5.3.8 build with this tool, then measures the gzip size with the browser's own compressor (Chromium).
| File | Source | Minified | gzip source → minified |
|---|---|---|---|
| Example 'Commented source' (6 comments) | 693 B | 461 B (−33.5%) | 444 B → 345 B (−22.3%) |
| Same example, all comments removed | 693 B | 414 B (−40.3%) | 444 B → 303 B (−31.8%) |
Bootstrap 5.3.8 bootstrap.css | 280,311 B | 232,759 B (−17.0%) | 33,326 B → 30,776 B (−7.7%) |
For reference: the official bootstrap.min.css | 280,311 B | 232,111 B (−17.2%) | 33,326 B → 30,823 B (−7.5%) |
On a large file like Bootstrap, minifying cuts 17% of the bytes but only about 8% of the gzip size, because gzip had already removed most of the whitespace. On a tiny file the opposite problem shows up: gzip adds a fixed 18 bytes of header and trailer (RFC 1952), so there is little for it to gain. Minifying still reduces the number of characters the browser has to read and parse, and where gzip is not used, the saving is the transfer size. Bootstrap's official minified file goes further, reordering selectors and rewriting values such as rgba(0,0,0,0) as transparent, so it is 648 B smaller, yet after gzip this tool's output was 47 B smaller. When the browser parsed this tool's output, all 2,660 entries, including the rules inside @media, came out identical to the original. The only difference was the whitespace next to commas in var() values.
The gzip figures use the browser's default settings, so they will differ somewhat from your server's compression level or from brotli. KB in the size map means 1 KB = 1,024 B.
Errors that make a rule disappear
CSS does not stop on an error. It throws away the broken part and keeps reading. That keeps the page from falling apart, but it never tells you what was dropped, which makes the cause hard to find. The six cases below follow how browsers actually read CSS (CSS Syntax 3), and the tool reads it the same way and reports each one under Findings with a line number.
| Error | How the browser reads it | In this tool |
|---|---|---|
A stray } outside a rule (.nav{…}}) | It is glued onto the front of the next selector, giving the invalid selector } .logo, and that whole rule is discarded (§5.5.3) | Names the selector that gets dropped and shows } .logo { in the output too |
An unclosed ( (calc(100% - 20px;) | Everything up to a matching ), including ; and }, is swallowed into the value, so every rule after it is lost | Points to the line of the opening bracket |
An unclosed { | Treated as closed at the end of the file. If another file is appended afterwards, all of it ends up inside this rule | Adds a } to the output and points to the line where it opened |
| A quote not closed by the end of the line | Read as an invalid string, and that declaration is dropped | Points to the line where the quote opened |
An unclosed comment /* | Everything to the end of the file becomes a comment | Points to the line where the comment started |
A declaration with no colon (font-size 20px) | Only that declaration is dropped, and reading resumes after the next ; (§5.5.6) | Shown as a warning |
The tool also lists a few things that are not errors but deserve a look. If the same property appears twice in one rule, only the later value applies. Since display: -webkit-box; display: flex; can be a deliberate fallback for older browsers, it is shown only as a note. An empty rule with no declarations is also noted, but minifying does not delete it.
Nested CSS and newer syntax are read as they are
CSS nesting lets you put &:hover { … } or @media straight inside a rule, and every major browser supports it now. The tool tells nested rules from declarations the way the specification does: inside a block, if a { shows up before a ; or }, it is a rule, otherwise it is a declaration. Formatting indents each level once. When minifying, it keeps the ; between a declaration and a nested rule that follows it.
| Feature | Chrome | Firefox | Safari | In this tool |
|---|---|---|---|---|
| CSS nesting (&) | 120 | 117 | 17.2 | Indented one level at a time; the ; between a declaration and a rule is kept when minifying |
@layer | 99 | 97 | 15.4 | Statement and block forms both keep their order, and empty blocks stay |
| gzip measuring (CompressionStream) | 80 | 113 | 16.4 | In older browsers the gzip line is hidden |
The versions are the first releases that support each feature, checked in MDN's browser compatibility data on 2026-10-22. From the versions above, nesting also covers rules that begin with a tag name, such as a { … }; Chrome 112 to 119 and Safari 16.5 to 17.1 did not support that form. Other at-rules such as @container, @supports, @scope and @property are read the same way.
Common mistakes
- Editing the minified file and minifying it again: you can format a minified file and edit it, but the comments that were removed do not come back. Keep the source file you edit separate, and make the minified copy from it at each release.
- Sorting properties alphabetically: in
margin-top: 8px; margin: 0;the later margin: 0 wins and the top margin is 0, but alphabetical sorting moves margin first, so margin-top: 8px wins and the top margin becomes 8px. This is why the tool has no sorting option. - Deleting /*! licence comments: much code, MIT-licensed code included, requires the copyright notice to stay in copies. When you minify someone else's CSS, keep the default (keep /*! only).
- Replacing every 0px with 0: some places need the unit, such as
flex: 1 0px, a keyframe0%andcalc(0px + 10%). Do not do it with a blanket find and replace. - Leaving SCSS // comments in CSS: CSS has no // comments. For the rule on the line after
// button, that text gets glued to the selector and the rule is dropped. If you see // in front of a selector in the formatted output, this is what happened. - Concatenating files when one is missing its last }: when you merge several CSS files, an unclosed block in the first swallows the whole of the next. Before merging, paste each file in and check that Findings is empty.
Limits and cautions
- It reads standard CSS only. SCSS and Less features such as $variables, @mixin and @include, // comments and arithmetic are not interpreted as CSS, so use the Sass or Less compiler, or Prettier, for those files.
- It does no structural optimisation: merging identical selectors, deleting overridden declarations, collapsing margin-top and friends into one margin, or tidying vendor prefixes. Build tools such as cssnano, Lightning CSS and esbuild do that kind of work.
- It produces no source map. A trailing
/*# sourceMappingURL=… */is an ordinary comment and is removed by the default minify setting, so switch comments to keep all if you need it. - The syntax check goes as far as brackets, quotes, comments and colons. It does not judge a misspelt property such as
colr: red, a wrong unit in a value or whether a browser supports something. - Files up to 5 MB open, and when the result is longer than 300,000 characters, syntax colouring is skipped for speed and plain text is shown.
- The gzip size is measured with the browser's default compression and may differ from your server's settings.
Reference date The W3C CSS specifications (Syntax 3, Values 4, Media Queries 4, Color 4, Flexbox 1, Cascade 5, Nesting 1) and MDN's browser compatibility data were checked against the original texts on 2026-10-22. The size table uses values measured the same day with Chromium's CompressionStream, and the Bootstrap figures are for the 5.3.8 distribution files.
Sources
- 01W3C: CSS Syntax Module Level 3CRD 2026-10-01. §4.3.2 comments, §4.3.5 strings, §5.5.3 a stray } at top level, §5.5.5 telling declarations from rules inside a block, §5.5.6 declarations without a colon
- 02W3C: CSS Values and Units Module Level 4WD 2024-03-12. §10.8 whitespace is required around + and − in calc(); * and / may have none
- 03W3C: Media Queries Level 4CRD 2026-02-19. §3 without a space between and, not or or and the ( the text becomes a function token
- 04W3C: CSS Color Module Level 4CRD 2026-10-20. §5.2 hex notation with 3, 4, 6 and 8 digits
- 05W3C: CSS Flexible Box Layout Module Level 1CRD 2025-10-14. §7.1 the unitless 0 in the flex shorthand
- 06W3C: CSS Cascading and Inheritance Level 5CR 2022-01-13. §6.4.3 layers are ordered by first declaration
- 07W3C: CSS Nesting Module Level 1WD 2026-01-22. Nested rules and the & selector
- 08MDN: browser compatibility dataChecked 2026-10-22. Nesting Chrome 120, Firefox 117, Safari 17.2; @layer 99, 97, 15.4; CompressionStream gzip 80, 113, 16.4
- 09cssnano: discardCommentsSpecial comments marked with ! (/*! … */) are kept by default
- 10IETF RFC 1952: GZIP file format10-byte header plus an 8-byte trailer (CRC32 and ISIZE)
- 11Bootstrap 5.3 distribution files5.3.8 dist/css/bootstrap.css and bootstrap.min.css (MIT), downloaded and measured 2026-10-22
Frequently asked questions
What is the difference between formatting and minifying CSS?
Formatting (beautifying) spreads declarations out one per line and fixes the indentation so a person can read the code. Minifying deletes comments, whitespace and line breaks that are not needed, leaving the meaning the browser reads unchanged, so the file gets smaller. Both results apply the same styles, so the safe routine is to keep the source you edit formatted and minify only the copy you publish.
Can minifying break my CSS?
A minifier that mechanically deletes all whitespace can. Removing the spaces around the minus in calc(100% - 2rem) makes the value invalid, and removing the space in .card :hover gives a different selector. This tool reads CSS token by token as the specification does and leaves those spaces, the unit on 0px and 0%, and anything inside strings and url() as they are. If the source is already broken, though, the output will be broken the same way, so fix the errors under Findings first.
Does minifying remove every comment?
By default only comments starting with /*! are kept and the rest are removed. /*! is the convention for licence and copyright notices, and minifiers such as cssnano keep them by default too. You can change the setting to remove all comments or keep all of them.
Why does the tool not turn 0px into 0?
Most of the time it would be harmless, but in a few places it changes the meaning. In flex: 1 0px, writing 0 makes the second number read as a shrink factor; 0% in @keyframes is invalid if written as 0; and calc(0px + 10%) stops being a valid calculation once it becomes 0. The saving is 2 or 3 bytes in a spot and even less after gzip, so keeping the unit was the safer choice.
Does it sort properties alphabetically?
No. When two declarations have the same priority, the later one wins. A rule with margin-top: 8px followed by margin: 0 has a top margin of 0, but sorting it alphabetically moves margin first, so margin-top: 8px wins and the top margin becomes 8px. The order stays as you wrote it, and Findings only reports properties that appear twice.
Why is a single stray } a problem?
A } left over outside a rule is not ignored by the browser. It is glued onto the front of the next rule's selector, giving something like '} .logo', which is invalid, so that one following rule is thrown away completely. It is a classic case where only part of the page looks wrong and the cause is hard to find, so the tool shows both the line and the selector that gets dropped.
Can it format SCSS or Less?
It reads standard CSS, so syntax that exists in CSS too, such as nesting (&) and declarations inside @media, is formatted. Syntax that exists only in SCSS and Less, such as // line comments, $variables, @mixin and @include and arithmetic, is not interpreted as CSS and the result may come out wrong. Use the Sass or Less compiler or Prettier for those files.
Is the CSS I enter stored or sent anywhere?
No. Formatting, minifying, size calculation and gzip measuring all happen inside this browser, and nothing is sent to a server or saved. The input disappears when you close the page, so copy the result or save it as a file if you need it.