Skip to content
TextArray
100% local

CSS formatter

Beautify minified or messy CSS into clean, indented, readable rules.

Input
Output

CSS formatter

Paste minified or hand-tangled CSS and this formatter expands it into a clean, readable stylesheet: one declaration per line, the selector and its opening brace on one line, the closing brace on its own, and a blank line between top-level rules. Nested blocks such as @media, @supports and nested selectors are indented one level deeper, so the structure of the sheet is obvious at a glance.

The tool reads your CSS character by character rather than splitting it with naive patterns, so it never breaks on tricky content. Strings keep their exact contents, so content: "a{b}" survives with the braces inside it. url() bodies are copied verbatim, so a data URI with its own semicolons and colons — url(data:image/png;base64,...) — is left completely alone. Comments stay word for word on their own line at the current indent.

Three options tune the output. Indent switches between two spaces, four spaces or a tab. One selector per line puts every selector of a comma list on its own row, handy for long grouped rules and cleaner diffs. Blank line between rules can be turned off when you want the sheet more compact. The live tally counts the rules, declarations and output lines as you type, with the rule count highlighted.

This is the counterpart to a CSS minifier: use it to make a compressed production file editable again, to reformat inconsistent code from several authors, or simply to read a stylesheet you did not write. Everything runs entirely in your browser — your CSS is never uploaded anywhere.

FAQ

Does it change my CSS values or property names?
No. It only adds and normalizes whitespace and line breaks. Selectors, properties, values, colors, units, url() bodies and comments are all preserved exactly as written.
Will braces inside strings or url() break the formatting?
No. A character scanner tracks string, comment and url() state, so content: "a{b}" and url(data:...;base64,...) are copied verbatim and never treated as structure.
What does "One selector per line" do?
It puts each selector of a comma-separated list on its own line, so h1, h2, h3 becomes three rows above the opening brace. Commas inside :is() or attribute selectors never split.
Can it fix invalid CSS?
It formats best effort and never errors on broken input, but it does not validate or repair your CSS. Missing braces or stray characters are laid out as well as their structure allows.
Is my CSS uploaded anywhere?
No. The formatting runs entirely in your browser and your CSS never leaves your device.