CSS Formatter Online

Paste CSS and get it back indented, highlighted and easy to read, or minified for production. It is for anyone reading a minified stylesheet from a CDN or a build, tidying CSS copied from DevTools, or shrinking a snippet before it goes into a page: choose 2 spaces, 4 spaces or tabs, one selector per line, and a blank line between rules.

Everything runs in your browser, so your CSS is not uploaded and there is no account. Modern CSS is understood, including nesting with &, @layer, @container and custom properties. If a brace, string or comment is never closed, or a semicolon is missing, DevPrix shows the line and column of the first problem, marks the line and still shows the output.

InputPaste, type or drop a .css file
Output
/*! Acme UI v2.4.0 | MIT */
:root {
  --brand: #4f46e5;
  --radius: .5rem;
  --shadow: 0 1px 2px rgb(0 0 0/.08),0 4px 12px rgb(0 0 0/.06);
}

*,
::before,
::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  color: #1f2937;
}

.card {
  padding: calc(var(--radius)*3);
  border-radius: var(--radius);
  box-shadow: var(--shadow);

  &:hover {
    transform: translateY(-2px);
  }

  & .title {
    margin: 0 0 .5rem;
    font-weight: 600;
  }
}

a:is(:hover, :focus-visible) > .icon {
  color: var(--brand) !important;
}

input[type="search" i]::placeholder {
  color: #9ca3af;
}

@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  .card {
    transition: transform .2s ease, box-shadow .2s ease;
  }
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }

  50% {
    opacity: .5;
  }
}
No syntax errors11 rules18 declarations11 selectors2 at-rules709 B → 885 BProcessed locally

How to use it

  1. Paste CSS into Input, or open or drop a .css file; it is checked and formatted as you type.
  2. Choose Formatted or Minified, an indent, and whether to put each selector on its own line and a blank line between rules.
  3. Press Format (⌘↵) to apply the result to your input, then copy, download or send it to another tool.

Related tools

HTML Formatter & MinifierFormatTailwind CSS LookupCSSCSS Gradient GeneratorCSSText Diff CheckerFormat

Next: compare two versions of a stylesheet in the Text Diff Checker, escape the CSS for a JavaScript string with String Escape, or hash the minified file for a Subresource Integrity attribute in the Hash Generator.

What this tool does

The tool splits your CSS into tokens the way browsers do (CSS Syntax Level 3), then groups them into rules, at-rules and declarations. Inside a block, an item that starts with a property name and a colon is a declaration, unless its value holds a { … } block next to other text: then it is a nested rule, so a:hover { … } inside .card { … } is read as a rule, just as a browser reads it. Formatting puts one declaration per line as property: value;, indents nested rules and at-rules such as @media, @supports, @container, @layer and @keyframes, adds a space after commas and around the > + ~ combinators, and writes media features as (min-width: 768px). It only ever changes whitespace and comments and adds or drops the optional ; before }. Strings, url() addresses, numbers, colours, escapes and the case of everything are kept as written, and custom property values (--name: …) are copied exactly, because they can hold almost anything, braces included. Minified mode removes comments except /*! … */ licence comments, the last ; in each block and every space that cannot matter, but keeps the ones that do: between compound selectors (.card .title), around + and - in calc(), and between values such as 0 auto. The check covers syntax, not meaning: an unknown property or an invalid value is formatted like any other.

Example input and output

Minified CSS with nesting, formatted with 2 spaces
Input
.btn{padding:.5rem 1rem;border-radius:6px;&:hover{background:#4f46e5}}@media (max-width:640px){.btn,.link{width:100%}}
Output
.btn {
  padding: .5rem 1rem;
  border-radius: 6px;

  &:hover {
    background: #4f46e5;
  }
}

@media (max-width: 640px) {
  .btn,
  .link {
    width: 100%;
  }
}
A missing semicolon
Input
.card {
  color: #1f2937
  margin: 0 auto;
}
Output
Line 2, column 17
Missing ; before margin
Without it, margin: … is read as part of the color value, and browsers drop both declarations.

Line 2, column 17 is the end of #1f2937, where the ; belongs. The output is still shown, with color: #1f2937 margin: 0 auto on one line, which is how a browser reads it.

Minify, keeping the spaces that matter
Input
/*! Theme v1 | MIT */
/* Card layout */
.card .title > a:hover {
  margin: 0 auto;
  width: calc(100% - 2rem);
  font-family: "Segoe UI", sans-serif;
}
Output
/*! Theme v1 | MIT */.card .title>a:hover{margin:0 auto;width:calc(100% - 2rem);font-family:"Segoe UI",sans-serif}

The licence comment stays and the other one goes. The spaces in .card .title, in 0 auto and around the minus in calc() stay too: removing any of them would change what the CSS means.

Common errors and fixes

Unclosed block: the { of .card has no matching }
A } is missing. Browsers close the block at the end of the file, so every rule after it ends up nested inside it and stops matching. The formatted output shows this as extra indentation from that point on: add the } where the rule should end.
Unexpected }: there is no { for it to close
An extra }, often left behind after deleting a rule, or a rule whose { is missing. Browsers do not just ignore it: they read it as the start of the next selector and skip that rule. Delete it, or add the missing {.
Missing ; before margin
The declaration above has no ;, so browsers read color: #1f2937 margin: 0 auto as one invalid value and drop both. Add the ; at the line and column shown. The same mistake before a nested rule is reported as Missing ; after color: red.
Unclosed string: the line ends before the closing "
A quote is missing in a content, font-family or url("…") value. A CSS string cannot span lines, so browsers drop the declaration that holds it. Add the closing quote, or end the line with \ to continue the string on the next line.
Unclosed comment: /* has no closing */
Everything after /* is part of the comment until */, here to the end of the file, so none of those rules apply. Add */ where the comment should end. Note that // is not a comment in CSS.
Invalid url(): an unquoted URL cannot contain spaces, quotes or parentheses
Write the URL in quotes, url("my image.png"), or percent-encode the character: %20 for a space, %28 and %29 for parentheses. Browsers drop the whole declaration otherwise.
Unexpected $: this looks like a Sass variable
The input is Sass (SCSS), not CSS. Variables, // comments, mixins and @include are compiled away by Sass; run your build, or sass styles.scss, and format the CSS it produces.

Common use cases

  • Reading minified CSS from a CDN, a WordPress theme or a production build
  • Tidying CSS copied from browser DevTools or a style attribute
  • Finding the missing brace or semicolon that breaks every rule after it
  • Minifying a snippet for an email template, a widget or an inline <style> block
  • Making two versions of a stylesheet comparable before diffing them

Privacy and security notes

  • Your CSS is formatted by JavaScript in this browser tab. It is not sent to DevPrix or stored on a server.
  • Nothing a stylesheet points to is loaded: @import and url() addresses, fonts and images are treated as text, so formatting a file never makes a network request.
  • Share copies a link that carries your input after the # in the URL. Browsers do not send that part to servers, but anyone you give the link to can read it.

Frequently asked questions

Does it support CSS nesting?

Yes. Nested rules, with or without &, are indented inside their parent, and @media or @supports inside a rule works too. The tool tells nested rules from declarations the way browsers do: inside a block, a:hover { … } is a rule, because a declaration's value cannot hold a { … } block next to other text, while --x: { … } is a custom property. A missing ; before a nested rule is reported, because browsers would read the declaration and the rule as one invalid rule.

Can formatting or minifying change how my CSS behaves?

It should not, and it has been checked against real stylesheets such as Bootstrap, Bulma and normalize.css to make sure. Only whitespace and comments change, plus the optional ; before } and ! important written as !important. Values are never rewritten: #FFFFFF stays #FFFFFF and 0.50 stays 0.50. A stray ; between top-level rules is kept, because browsers read it as part of the next selector and skip that rule; it is reported as an error instead of being silently fixed.

Does it check that properties and values are valid?

No. It checks syntax: braces, brackets, strings, comments, url(), colons and semicolons. A misspelt property such as colr: red or an invalid value such as width: 10 is formatted like any other declaration, and browsers ignore it. To catch those, use the Styles panel in your browser's DevTools, which crosses out invalid declarations, or a linter such as Stylelint.

Can it format SCSS, Less or Tailwind files?

It reads plain CSS. Tailwind directives such as @tailwind, @apply and @theme, and other at-rules it does not know, are kept as written, with only their spacing tidied. Sass and Less syntax (variables like $brand or @brand, // comments, mixins) is not CSS: compile it first. Nested rules written for Sass are often valid CSS nesting too and format fine.

How much smaller does minifying make a stylesheet?

It depends on how much of the file is whitespace and comments: about 10 to 20 percent for a large framework, and far more for a heavily commented file such as normalize.css, which goes from 6,138 to 1,851 bytes. Bootstrap 5.3.3's bootstrap.css goes from 281,043 to 233,470 bytes here, within 0.3 percent of the official bootstrap.min.css. Tools such as cssnano and Lightning CSS save a little more by rewriting values and merging rules; this tool leaves values and rule order exactly as written. Serving the file with gzip or Brotli compression saves far more than either.