flashman
← All guides

Beautify CSS only when every semicolon is a declaration

Run the CSS beautifier on plain declarations, and keep comments, content strings, and data URIs out of a transform that splits on every semicolon.

2026-10-19 · 8 min read

  • css
  • formatting
  • tooling

The CSS page minifies, and beautify is that minify plus newlines. Minify deletes a comment that has both /* and */, collapses every whitespace run to one space, then deletes spaces beside braces, colons, semicolons, and commas. Beautify breaks after each remaining semicolon and around each brace. Nothing in that pipeline is a CSS parser.

Use it on a rule whose semicolons are declaration separators and whose values have no comments you need to keep. Keep a stylesheet that fails those tests in the editor that parsed it.

Save comments before the first step

The comment deletion is not optional and it does not spare a license banner. /*! license */ is removed when the closer is present. The rule that followed it remains. An unclosed comment stays, because the pattern never sees */. That leftover is not a preserved comment feature. It is the match failing.

Newlines between rules are whitespace, so they collapse. Two compact rules on neighboring lines become adjacent selectors with nothing between the closing brace and the next selector. Valid, and noisier in a line-based diff than the indentation change alone.

  • Lift license text out of the file you are about to beautify.
  • Search for /* before you run the tool.
  • Expect a blank line between rules to vanish.
  • Do not reopen an unclosed comment to force a delete.

Treat strings and data URIs as unsafe input

content:"hello; world" loses the space around the semicolon during minify, then loses the string during beautify. The declaration is broken across two lines at hello; and world". A data URI with a semicolon, such as data:image/svg+xml;base64, is broken at that semicolon too. The colon in data: is left in place because no space was wrapped around it.

A space that is not next to those five characters survives. padding: 8px 12px keeps the space between the lengths and loses the space after the colon. That split is why the output looks tighter than a typical formatter and still wrong inside a quoted value.

Read the shape of a safe result

A safe sample such as .btn { color: white; background: black; padding: 8px 12px; } comes back with the selector and opening brace on one line, each declaration unindented and without a space after the colon, the closing brace on its own line, and a trailing newline. There is no two-space indent step. A formatter comparison that expects indent will flag every line.

At-rules are text. @media (min-width: 600px) loses the space after the colon inside the query and still receives brace newlines. If the query had contained a semicolon, it would have broken too.

Decide from a search, then diff

Search the source for content:, url(, and /*. Any hit is a reason to skip this beautifier. A file of plain color, margin, and display declarations is the file this tool can tidy. Diff the result even then, because comment removal and the missing indent are real edits.

Use the CSS tool for that tidy pass, the regex tester for the search, diff for the before and after, and the color tool when the declaration is a six-digit hex you want a contrast ratio for. The beautifier will not compute that ratio, and it will not protect a string.

Try these tools