Skip to content
FormatKit

Free online CSS minifier

Minify CSS with only the safe shortenings

Whitespace and comments come out, and three value shortenings go in — #ffffff to #fff, 0px to 0, 0.5 to .5 — each with its own switch. Free, no signup, nothing uploaded. What does not happen is the part worth knowing: no rule is merged with another, no declaration is reordered or deduplicated, and no shorthand is rewritten, because a stylesheet is an ordered document and half its fallbacks depend on that. A 517-byte theme loses 28%, a 44.8 KB sheet 25%, and the gzip cell tells you how much of that survives compression.

  • 100% free
  • No signup
  • Up to 5 MB
  • Cascade order kept
  • 3 safe shortenings
Minified

The one-line stylesheet appears here.

Paste a stylesheet, drop a file, or press Ctrl+V anywhere on this page.

Left exactly as you wrote it

  • Custom property values. --gutter: 0px 16px keeps its unit, because whatever consumes it may be doing arithmetic.
  • Anything inside calc(), min(), max() or clamp(), where a unitless zero is a type error.
  • Times and angles. 0s may not become 0 in a transition; only the fifteen length units drop theirs.
  • Selector order, shorthand properties, duplicate rules and url() contents.

To read a minified sheet rather than make one, the CSS formatter puts every declaration back on its own line.

How to minify CSS

Paste it, tick the shortenings you trust, weigh the result.

  1. Load the stylesheet

    Drop it into the left pane, paste with ⌘V or Ctrl+V without focusing the box first, or open a .css file. Sample theme drops in a small sheet with banners, custom properties and a calc() in it, which is the quickest way to see which values get shortened and which are pointedly left alone.

  2. Choose the shortenings

    Three checkboxes, each independent: hex colours down to their short form, zeros down to bare 0 and .5 for 0.5, and licence /*! banners kept or dropped. All three are on by default. Untick a shortening and that class of edit stops entirely — useful when a downstream tool of yours parses the file and is fussy about the form values arrive in.

  3. Check the tally and ship it

    The status line counts rules kept in order, declarations, comments dropped, and how many colours and numbers were shortened in your particular file. The four cells give bytes before and after, the saving, and the gzip pair. Download saves it as .min.css.

Technical specifications

RemovedAll optional whitespace and newlines, every comment except /*! banners when that box is ticked, and the final semicolon in each block
Three safe shortenings#aabbcc → #abc and #aabbccdd → #abcd; a zero with any of 15 length units (px, pt, pc, in, cm, mm, Q, em, rem, ex, ch, vw, vh, vmin, vmax) → 0; a leading zero before a decimal point → .5. Each has its own checkbox
Never shortenedTimes and angles (0s, 0deg), percentages (0%), anything inside calc(), min(), max() or clamp(), custom property values, string contents, url() bodies, trailing zeros (1.0rem stays), and negative numbers keep their leading zero
Structure preservedRule order, duplicate rules and duplicate declarations, shorthand versus longhand, vendor prefixes, selector text and case, and every at-rule prelude. Nothing is merged, sorted or deduplicated
Measured saving517-byte hand-written theme → 28% off raw, 17% off gzipped; 44.8 KB sheet → 25% raw, 5% gzipped; the same sheet with comments already gone → 21% raw. Comment density decides most of it
Against a production buildRe-minifying a shipped 25.2 KB Tailwind stylesheet returns a file the same size as the one the build produced, so the whitespace layer here is as tight as a real pipeline's — the difference between the two is optimisation, not sloppiness
When it declinesUnterminated string, unterminated /* comment, unterminated url(), a } with no matching {, or a file that stops mid-block: your text comes back byte for byte with the reason
Limits and measurement5 MB per stylesheet, one at a time, parsed and compressed in your browser. The gzip figure is a real measurement where the browser offers a compression API and is labelled estimated where it does not

Frequently asked questions

Which value shortenings are applied, and why only these?

Three, because three are provably reversible by the browser's own parser. A six-digit hex colour whose digits pair up becomes three — #ffffff is #fff, and the eight-digit form with alpha collapses to four the same way — which is a syntax the spec defines as identical, not an approximation. A zero with one of fifteen length units on it becomes a bare 0, since a length of zero is the same length whatever unit it was written in. A leading zero before a decimal point goes, because .5rem and 0.5rem are the same token to the tokeniser. Everything else that would make the file smaller changes something about the sheet, so it is left out.

Why does 0px lose its unit when 0s keeps one?

Because a unitless zero is a length, not a time, and transition and animation shorthands are parsed positionally. Write transition: box-shadow 0s ease and drop the s and the browser reads the 0 as the wrong component of the shorthand — a rule that quietly stops animating. Angles behave the same way: rotate(0deg) needs its unit, since rotate(0) is only valid because the function coerces it, and inside a transform list the coercion is not guaranteed. Percentages are excluded too, as 0% and 0 are genuinely different in a gradient stop. Only the fifteen length units lose theirs.

Why are my custom properties left completely alone?

A custom property is a token stream waiting for substitution, not a value with a known type. --gutter: 0px 16px could be consumed by a property that needs the unit, split apart by JavaScript reading getPropertyValue, or dropped into a calc() where a bare 0 is a type error. The minifier cannot know which, and being wrong means a layout that silently collapses, so everything to the right of a -- property's colon is copied out exactly as written — spacing included. The same caution applies inside calc(), min(), max() and clamp() wherever they appear.

Does it merge duplicate rules or reorder declarations?

No, and that is the single biggest difference between this and an optimising minifier. Combining two rules that share a selector, folding four longhands into a shorthand, or dropping what looks like a duplicate declaration all assume the sheet has no order-dependent tricks in it — and real sheets are full of them: a fallback declaration written before the modern one so old browsers take the first and new ones take the second, a duplicate property used as a targeted hack, a deliberate override sitting later in the cascade. Your rules come out in your order, one for one, with the same selectors.

How much smaller does a stylesheet get?

A quarter or so of the raw bytes, and much less than that once compression has had a look. A 517-byte hand-written theme with comments came out 28% smaller, or 17% after gzip. A 44.8 KB sheet lost 25% raw but only 5% gzipped, because it was repetitive enough that the compressor had already dealt with most of what got deleted. The spread between those two figures is the point — measure your own file rather than trusting a rule of thumb, and read the gzip cell rather than the raw one whenever the file will be served compressed.

Are strings, data URIs and !important safe?

All three come through intact. A quoted font name keeps the comma inside it, so "Foo, Bar", sans-serif does not lose the name it was pointing at. A data URI sitting inside an unquoted url() travels as a single token, payload punctuation and all, since one stray space in an unquoted URL is enough to make it invalid. content strings keep their exact characters, braces and all. !important keeps its space before the bang, and the property it is attached to keeps its place in the cascade.

What stops it from minifying a sheet?

An unterminated string, an unterminated /* comment, an unterminated url(), a } with no opener, or a file that simply runs out mid-block. Any of those and you get your text back unchanged with the reason named, rather than a smaller file that has lost a rule. This matters more for minifying than for formatting: a stylesheet that came back mangled will still load, apply most of itself, and fail in one place you will not find until someone reports it.

About safe versus clever CSS minification

Every CSS minifier removes the same whitespace. What separates them is the list of transformations they are willing to apply on top, and that list is where the interesting arguments live. Some are indisputable: #ffffff and #fff are the same colour by definition, and a zero length is a zero length whether it was written in pixels or rems. Some are indisputably not: 0s is a duration and loses its meaning as a bare zero inside a transition shorthand. This tool implements the first group, refuses the second, and shows you the count of each edit it made so the diff is never a surprise.

The transformations left out are the structural ones, and they are left out because stylesheets encode intent in their order. A pair of declarations written one after the other is often a fallback strategy — the old syntax first so an old engine takes it, the new one second so a current engine overrides it — and a minifier that spots a “duplicate” and deletes one has removed support for a browser you were deliberately serving. Merging two rules with the same selector moves every declaration in the later one earlier in the cascade. Folding four longhands into a shorthand resets the properties you did not mention. Each of those is usually fine and occasionally catastrophic, and a text box on a website is a poor place to find out which. That judgement belongs to a build tool you can configure and test.

Watch the gzip cell rather than the raw one. CSS compresses extremely well — a utility build is thousands of near-identical declarations, so a quarter off the raw file can be a twentieth off the wire — while a small hand-written theme keeps much more of its saving. Both numbers are measured on your file, not assumed. If you need the reverse operation because the sheet you are holding is unreadable, the CSS formatter expands it; if the styles you are shrinking live inside a page rather than a file, the JavaScript minifier is the companion for the other half of that page’s weight.

Where your stylesheet is minified

Everything happens in this tab: the parse, the shortenings, and the compression used for the gzip figure. Your sheet is not uploaded, and no font or image it references is requested — a url() is treated as a run of characters and nothing more.