CSS Beautifier

Pretty-print or minify CSS with configurable indent, selector separator, and brace style. 100% local.

formatters

CSS Beautifier / Minifier

Input
Output

Runs entirely in your browser. Your input never leaves your device.

What next?

How it works

Why formatted CSS is worth the effort

CSS has no required whitespace. A browser parses a{color:red} and a { color: red; } identically. But humans don't read them identically. A stylesheet that arrives from a CMS, a legacy project, or a third-party vendor as one long line is nearly impossible to reason about — you can't see rule boundaries, selector chains, or declaration groupings at a glance.

Formatting CSS is also a precondition for useful version control. A git diff on minified CSS shows one enormous changed line even when a single color value changed. Beautified CSS shows exactly which property changed, on which selector, in which rule block.

One selector per line — why it matters for diffs and readability

A grouped selector like:

h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  line-height: 1.25;
}

is fine for reading, but a code review that adds h6 or removes h4 modifies one mixed line. The diff is noisy. The beautified form puts each selector on its own line:

h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: 600;
  line-height: 1.25;
}

Now adding or removing one heading level is a clean one-line diff. This is the default behavior of js-beautify's CSS mode and the format used by Prettier for CSS. The selector separator option in this tool controls this: set it to a newline for one-per-line, or a space to keep selectors grouped.

Specificity readability

CSS specificity determines which rule wins when two rules target the same element. The calculation (inline styles → IDs → classes/attributes → elements) is easier to reason about when each rule is fully indented and isolated. Minified stylesheets flatten everything to one line — you have to mentally parse the cascade at the character level.

During development, keep CSS beautified. During code review, a formatted diff makes specificity conflicts visible before they reach production.

Minification: real byte savings

CSS minification removes:

  • All whitespace between tokens (spaces, tabs, newlines)
  • Comments (/* ... */)
  • Trailing semicolons in rule blocks (the last declaration before } doesn't need one)
  • Leading zeros in decimals (0.5em.5em)
  • Redundant quotes in some contexts

A realistic stylesheet might shrink 25–40% after minification. Here's the key nuance: HTTP compression (gzip or brotli) is vastly more effective than raw whitespace removal. Gzip typically achieves 60–80% compression on CSS because whitespace is highly repetitive and compresses well. The order of magnitude difference:

| File | Raw | After minify | After gzip | After minify + gzip | |------|-----|-------------|-----------|-------------------| | bootstrap.css | 187 KB | 153 KB | 26 KB | 24 KB |

The right call: enable gzip/brotli on your server (virtually all do by default), and also minify CSS in your build pipeline. The combined savings are the best of both.

CSS Nesting (CSS Nesting Module Level 1)

Modern CSS supports nesting without a preprocessor. The CSS Nesting Module Level 1 specification (now supported in all evergreen browsers) allows:

.card {
  padding: 1rem;

  & .title {
    font-size: 1.25rem;
  }

  &:hover {
    background: var(--color-hover);
  }
}

js-beautify's CSS mode preserves nesting indentation correctly. Minification collapses nesting to the minimum-whitespace representation while keeping the nesting structure valid — it does not "de-nest" to flat CSS.

Shorthand vs longhand in minified output

CSS shorthands like margin: 0 auto are smaller than margin-top: 0; margin-right: auto; margin-bottom: 0; margin-left: auto. However, automatically converting longhand to shorthand during minification is risky because shorthand resets all sub-properties, not just the ones you list. A minifier that blindly converts longhand to shorthand can change cascade behavior.

js-beautify does not do shorthand conversion — it only removes whitespace. For shorthand optimization, tools like cssnano with the postcss-merge-longhand plugin handle this with proper cascade analysis.

Source maps for debugging minified CSS

When serving minified CSS in production, generate a source map so browser DevTools shows the original beautified line and file even when running minified code:

# PostCSS with cssnano
npx postcss styles.css --use cssnano -o styles.min.css --map

The resulting .map file maps minified byte offsets back to original source lines. DevTools automatically fetches it when the minified file contains /*# sourceMappingURL=styles.min.css.map */ at the end.

Using js-beautify for CSS

import beautify from 'js-beautify';

const pretty = beautify.css(rawCss, {
  indent_size: 2,
  indent_char: ' ',
  selector_separator_newline: true,  // one selector per line
  end_with_newline: true,
  newline_between_rules: true,       // blank line between rule blocks
});

For production minification, prefer cssnano (PostCSS-based) or lightningcss (Rust-based, extremely fast):

import { transform } from 'lightningcss';

const { code } = transform({
  filename: 'styles.css',
  code: Buffer.from(rawCss),
  minify: true,
  sourceMap: true,
});

Privacy

All CSS processing runs entirely in your browser. Your styles are never transmitted to a server.

FAQ

Will beautifying CSS change how my styles apply?

No. CSS whitespace outside string values and content properties is insignificant to the browser's parser. Indentation, newlines between rules, and spaces around colons are all ignored at render time. The computed styles your page produces are identical before and after formatting.

Why is one selector per line the default in beautified CSS?

Placing each selector on its own line produces cleaner git diffs. When a grouped selector like h1, h2, h3 { ... } gains or loses one entry, a single-line format marks the entire selector line as changed. One-selector-per-line means adding h4 or removing h2 shows as a single-line diff with no noise. This is also why Prettier uses this format for CSS by default.

How much does CSS minification actually save?

Raw whitespace removal typically reduces CSS by 20–40% depending on coding style. However, the more important factor is HTTP compression: gzip reduces CSS by 60–80% because whitespace is highly repetitive. Minification and gzip are complementary — use both in production. Minify first in your build pipeline, then let your CDN or server apply gzip/brotli on top. The combined result consistently beats either technique alone.

Does this tool support CSS Nesting?

Yes. js-beautify preserves CSS Nesting syntax (the CSS Nesting Module Level 1, supported in all evergreen browsers) including the & selector. Both beautify and minify modes handle nested rules without de-nesting them to flat CSS.

What is the selector separator option?

It controls how selectors in a grouped rule are separated. Set to newline (the default) for one selector per line — preferred for readability and diffs. Set to space for compact grouped selectors on one line. Neither changes how the rule is applied; it is purely a formatting preference.

Should I use this tool or integrate cssnano into my build pipeline?

Both. Use this tool for ad-hoc formatting — pasting CSS snippets, cleaning up a one-off stylesheet, or examining third-party CSS. For automated production minification, integrate cssnano (PostCSS-based) or lightningcss (Rust, extremely fast) into your build step. Build-pipeline tools can also do shorthand merging, deduplication, and dead-code elimination that a browser-based tool cannot.

How do I debug my minified CSS in production?

Generate a source map during the build step (--map flag in PostCSS, sourceMap: true in lightningcss). The map file links minified byte offsets back to original source lines. Browser DevTools automatically fetches the map and shows you the original file and line number when you inspect a styled element, even though the browser is loading the minified file.

Does minifying CSS remove my comments?

Yes — standard CSS minification strips all /* ... */ comments. If you have important comments that must survive (copyright headers, /*! license */ style), use the ! convention: /*! Copyright ... */. Most minifiers preserve comments starting with !. js-beautify minification removes all comments; for preserving license headers in production use cssnano with { discardComments: { removeAllButFirst: true } }.