Skip to content
FindTool

    CSS Minifier

    Minify CSS safely, preserving strings, custom properties and licence comments.

    CSS Minifier tool

    Minified CSS

    What this tool does

    Paste a stylesheet and it comes back with comments gone, whitespace collapsed, the final semicolon of each block removed and numbers trimmed to their shortest legal form — along with the before and after byte counts and the percentage saved. A typical hand-written stylesheet loses between 15% and 30%.

    Unlike the regular-expression minifiers that dominate search results, this one reads the stylesheet as tokens, so it knows a semicolon that ends a declaration from one sitting inside a string or a data URI.

    Common uses

    • Shrinking a stylesheet for a project that has no build step — a landing page, an email template, a WordPress theme.
    • Compacting the critical CSS you are about to inline into <head>, where every byte is on the critical rendering path.
    • Producing a single-line value to embed in a JavaScript string or a CMS field.

    A short example

    This input:

    .card {
      margin : 0.5rem   0 ;   /* top and bottom */
      width  : calc( 100% - 2rem ) ;
    }

    becomes:

    .card{margin:.5rem 0;width:calc(100% - 2rem)}

    Note what survived: the space between .5rem and 0, because they are two separate values, and the spaces around the minus inside calc(), because removing them makes the expression invalid.

    What a regex minifier gets wrong

    Four constructs break naive minification, and all four appear in ordinary stylesheets. A string can contain anything: content: "a; b {c}" has a semicolon and a pair of braces that are data, not structure. An unquoted url() can contain a semicolon and a colon — every base64 data URI does. A custom property's value is not CSS at all but an arbitrary token stream, so it must be copied out verbatim rather than reformatted. And a comment opener inside a string, content: "/*", will make a comment-stripping regex eat the rest of the file.

    The tokenizer handles each of those as one indivisible unit, then decides about whitespace a token pair at a time, tracking selector and declaration contexts separately. That matters: in a selector div :hover and div:hover select different elements, so the space before a colon is load-bearing; in a declaration it never is. Likewise @media screen and (min-width:40em) must keep the space before its bracket, or and ( fuses into a function token and the breakpoint stops working.

    Worth knowing

    Minification is a fraction of the win that compression is. A stylesheet that drops 20% here will usually drop 80% under gzip, because repeated property names compress beautifully. The two stack, but if you can only do one, enable compression on the server. This tool also stops short of what a full optimiser such as lightningcss does: it does not merge duplicate selectors, reorder declarations or drop rules for browsers you no longer support. Those change the cascade in ways that need a test suite behind them, and this page has none of your tests.

    Frequently asked questions

    Why can’t a minifier drop the unit from every zero?

    Because only lengths may lose it. CSS allows 0px to shrink to 0, but a time, angle, frequency or resolution value requires its unit, so transition-duration: 0s is valid where a bare 0 is not. Inside calc() the rule tightens again: a unitless zero is a plain number rather than a length, which makes calc(100% - 0) invalid while calc(100% - 0px) parses.

    Why did my @import stop working after I inlined the minified CSS?

    Position, not minification. An @import is honoured only when it precedes every rule except @charset and @layer, so pasting a stylesheet below existing declarations in a style element makes the browser drop the import — silently, with nothing in the console. Move imports to the top of the combined file, or resolve them at build time; each one costs an extra round trip on the critical path regardless.

    Why is my stylesheet still huge after minifying?

    Minification removes characters, never rules. A framework build ships every selector it defines whether a page uses eight of them or eight hundred, and that dead weight is usually most of the file. Chrome DevTools’ Coverage panel reports the unused share against a real page load, and content-aware tooling such as Tailwind’s build step or PurgeCSS is what actually deletes those rules — a far larger win than whitespace.