ToolActToolAct

CSS Formatting Tool

Input CSS
Output
Lines: 1Characters: 0Bytes: 0
Lines: 1Characters: 0

What is CSS Formatting?

The CSS Formatter organizes stylesheets into a consistent, readable structure. Selectors, declarations, media queries, keyframes, variables, and preprocessor output become easier to inspect than in minified or unevenly indented code. This helps debugging, code review, design-system maintenance, teaching, and understanding styles copied from another source. Formatting does not automatically change the cascade, specificity, inheritance, or browser compatibility. A small-looking rule can still have a large effect if it loads late or uses a strong selector. For production changes, responsive states, visual regression, lint rules, build output, and the surrounding component structure should still be checked.

How to Use

How to use

  1. Paste or enter CSS code in the left input box
  2. Select indent size and format style
  3. Click "Format" to beautify code, or click "Minify" to reduce size
  4. View results on the right with syntax highlighting
  5. Click "Copy" to copy to clipboard

Format Style Options

ExpandedEach property on its own line, suitable for development and debugging
CompactSelector and properties on the same line, suitable for quick browsing

Keyboard Shortcuts

  • Ctrl + EnterFormat
  • Ctrl + Shift + CCopy result

Formatting Tips

  • Formatting changes whitespace and layout, not selector behavior; still test the stylesheet after editing complex cascade or media-query code.
  • Minify only when the output will be used for delivery or embedding. Keep a readable source copy for review and maintenance.

Use Cases

Turn compressed CSS into readable rulesPaste CSS from a bundle, CMS field, browser devtools, or email template and format it with 2 spaces, 4 spaces, or tabs so selectors, declarations, and nested media blocks are easier to review. Once expanded, the rule order also becomes auditable, which helps when chasing a cascade override or a media query that fires later than expected.
Minify edited CSS for a small handoffAfter changing a snippet, switch to minify mode to remove comments and unnecessary whitespace, then copy or download the result as a CSS file for quick embedding in an email template, codepen prototype, or static page. Format the readable version first so it stays clear which selectors changed, and validate the minified result with stylelint or a project linter pass since minification does not check selector specificity, duplicate properties, or unintended cascade overrides.
Use it for snippets, not full CSS parsing guaranteesThe formatter is a lightweight browser implementation that preserves quoted strings, url() contents, and comments inside declarations, but does not replace a full PostCSS pipeline for vendor syntax, source maps, linting, or production build validation. Compile Sass, Less, or CSS Modules down to plain CSS first, then pass the output through this tool for review snapshots; rely on stylelint, PurgeCSS, or a CSS audit tool for the production check.
Normalize vendor-prefixed or preprocessor outputFormat compiled output from Sass, Less, or PostCSS so -webkit-, -moz-, and -ms- prefixes line up and the cascade order of media queries is visible at a glance during code review. The expanded block also makes nested @supports or @container rules easy to spot when auditing cascade priority.
Choose indent width that matches the project style guidePick 2 spaces, 4 spaces, or tabs up front so the formatted snippet drops straight into the repo without a follow-up linter pass, which matters most when pasting into a shared design-system file. Two spaces tend to keep deep nesting readable, while tabs let each contributor pick their own visual width.

Technical Principle

CSS formatting is a tokenising + pretty-printing problem, not a full parse. A spec-compliant CSS parser (CSS Syntax Module Level 3, W3C Recommendation) is heavier than a formatter needs: it builds an AST with style rules, at-rules, declarations, and component values, and resolves parsing edge cases (unterminated strings, mismatched braces, vendor-prefixed properties). This page uses a lighter tokenizer that walks the character stream, recognises the same token classes (ident, at-keyword, hash, string, bad-string, number, dimension, percentage, url, function, punctuation, comment), and emits them as a flat list, then the pretty-printer reassembles the tokens with the chosen indent, brace style, and whitespace rules. The two structural units in CSS are rule blocks (selector { declarations }) and at-rule blocks (@media, @supports, @container, @keyframes wrap one or more rule blocks). The formatter walks a token stream and tracks brace depth: a `{` increments depth (and a newline + indent follows), a `}` decrements depth (and the indent shrinks to match the matching `{`). Selectors are emitted verbatim — the formatter does not parse them, because parsing a selector like `.foo > .bar:hover:not(.baz)` is a separate problem (CSS Selectors Level 4). Selectors are kept byte-for-byte, only with whitespace normalised (multiple spaces collapsed to one, trailing whitespace removed) so a minified `.a,.b,.c` round-trips to `.a, .b, .c`. Declarations are formatted with a chosen style: 'expanded' (each property on its own line, the most readable), 'compact' (one rule per line, multiple declarations packed, the most common in production CSS), or 'compressed' (minified, no whitespace at all, the smallest possible output). The colon after the property name is always followed by one space; the value is emitted verbatim except for a few normalisations (trailing zeros stripped from `0.500` to `.5`, units removed from `0px` to `0`, the classic CSS minification tricks). Minification is the reverse direction: strip comments, collapse whitespace inside and between declarations, drop the trailing semicolon after the last declaration in a block (legal per CSS 2.1 §4.1.7), merge adjacent rule blocks with the same selector and media context, and normalise colour values (`#ffffff` -> `#fff`, `rgb(255,255,255)` -> `#fff` when possible). Modern minifiers (cssnano, lightningcss, clean-css) also do structural optimisations: merging longhand into shorthand (`margin-top: 1px; margin-right: 1px; margin-bottom: 1px; margin-left: 1px;` -> `margin: 1px;`), removing duplicate declarations within a rule, and removing rules that match no element (`div:has-no-children { color: red; }` in dead-code-elimination passes). For minified output the page applies the standard transforms; for human-readable output the page applies the chosen indent and brace style. The CSS Nesting Module (CSSWG, drafted 2023, Baseline 2024) introduces native nesting: `.a { color: red; & .b { color: blue; } }` is now valid CSS in modern browsers (Chrome 112+, Firefox 117+, Safari 16.5+). Pre-2024 nesting required preprocessor rewrites (Sass `&` or Less `&` to chain selectors). The page handles both: preprocessor-nested CSS is formatted as if it were SCSS / Less (preserving the `&`), and native-nested CSS (no `&` required) is formatted by the rule-block walk regardless. Other at-rules the page handles: @keyframes and @counter-style take a body of declarations, not nested rule blocks, so they format differently (declarations inside the at-rule, no nested brace). @media, @supports, @container, @layer take a body of rule blocks. @import, @charset, @namespace are top-level only and emit on their own line. @property (registered custom properties) takes a declaration block. @font-face is a single rule block with a complex selector-less declaration. The page treats each by its spec-defined body shape, not by its name. The most common formatting pitfall is breaking content inside string literals: `content: "hello world";`, `font-family: "Arial Black", sans-serif;`, `background: url("image.png")` — the formatter must not collapse the space inside the string, must not split the URL on `/`, and must not touch the comment text inside `/* ... */`. A tokeniser that correctly tracks the string-state and comment-state is the difference between a formatter that round-trips user content and one that mangles it. The page's tokenizer is hand-rolled and is small enough to verify by eye; production formatters use postcss or lightningcss, which carry the same obligation in their internal lexers.

  • Lexical analysis (CSS Syntax Level 3): walk the character stream, emit ident / at-keyword / hash / string / number / dimension / percentage / url / function / punctuation / comment tokens. Strings and comments have state — a misbehaving tokenizer breaks `content: "hello world";`.
  • Two structural units: rule blocks (selector { declarations }) and at-rule blocks (@media, @supports, @container, @layer wrap rule blocks). The formatter walks brace depth and indents each `{` to a new level; matching `}` shrinks the level.
  • Selectors are emitted verbatim, with whitespace normalised: `.a,.b,.c` -> `.a, .b, .c`. The formatter does not parse selectors (CSS Selectors Level 4 is a separate problem) — it just cleans spaces and commas.
  • Output styles: 'expanded' (one declaration per line, most readable), 'compact' (one rule per line, common in production), 'compressed' (no whitespace, minified). The colon + space after the property name is the only universal format rule.
  • Minification: strip comments, collapse whitespace, drop trailing `;`, merge same-selector rules, normalise `#ffffff` -> `#fff`, `0.500` -> `.5`, `0px` -> `0`. Structural merges: longhand -> shorthand (`margin-top: 1px; ... margin-left: 1px;` -> `margin: 1px;`).
  • CSS Nesting (CSSWG 2023, Baseline 2024): `.a { & .b { ... } }` is now native CSS in Chrome 112+, Firefox 117+, Safari 16.5+. Pre-2024 preprocessor nesting (Sass `&`, Less) is still valid; the page formats both by walking the rule-block structure.
  • At-rule bodies: @keyframes and @counter-style take declarations; @media / @supports / @container / @layer take rule blocks; @import / @charset / @namespace are top-level statements; @property and @font-face take declaration blocks. The page treats each by its spec-defined body shape, not its name.
  • Safety boundary: string literals (content, font names, URLs) and comment text are left untouched by every transform. A byte-exact round-trip is the correctness test for a CSS formatter — break a content string and the user notices immediately.

Examples

Minified CSS Formatting

Input:  .btn{color:red;background:#fff;padding:8px 16px;border-radius:4px}
Output:
.btn {
  color: red;
  background: #fff;
  padding: 8px 16px;
  border-radius: 4px;
}

Expanding Nested Rules

Input:  .card{padding:16px}.card h2{margin:0 0 8px}.card p{color:#666}
Output:
.card {
  padding: 16px;
}
.card h2 {
  margin: 0 0 8px;
}
.card p {
  color: #666;
}

Media Query Formatting

Input:  @media(max-width:768px){.nav{display:none}.menu{width:100%}}
Output:
@media (max-width: 768px) {
  .nav {
    display: none;
  }
  .menu {
    width: 100%;
  }
}

FAQ

What does the CSS formatter do?

Reformats CSS into readable layout: consistent indentation, one declaration per line, spaces around colons, and one rule per line. Doesn't change selector specificity or property values - purely whitespace and bracket placement.

Will it minify CSS too?

Yes if there's a 'minify' or 'compress' toggle. Minification strips comments and whitespace, shortens hex colors (#ffffff → #fff), and removes the trailing semicolon of the last declaration in a rule. The reverse direction (beautify) restores readability.

Why didn't it fix my invalid CSS?

It's a formatter, not a validator. Unmatched braces, missing semicolons, or unrecognised properties pass through. Use a CSS linter (Stylelint) or load your CSS in a browser dev-tools panel to see syntax errors.

Does it handle modern CSS (nesting, container queries, custom properties)?

Most builds use a CSS parser that understands current syntax including @container, @supports, custom properties (--var), nesting, and @layer. If the parser is older, novel syntax may format awkwardly - paste your CSS and inspect the result before using.

Will my comments be preserved?

Yes. /* ... */ block comments are preserved by the formatter. Some minifiers strip comments by default; turn that off if you need them. Single-line // comments are not standard CSS and may be removed (they live in SCSS, not CSS).

Is the CSS uploaded?

No. Formatting happens in your browser using a JavaScript CSS parser/printer. Pasted CSS is not transmitted.

Can I configure indentation?

Yes - typically 2 or 4 spaces, or tabs. Pick what matches your project's existing style. Mixed indentation in the original is normalized to your chosen value.