CSS to SCSS Converter

You inherited a 3,000 line stylesheet and a ticket to move it onto Sass. Paste it here to get rules nested by selector, breakpoints sitting next to the declarations they override, and repeated colors named once at the top.

.css
SCSS output.scss

Nested rules land here, with a variable block on top when values repeat.

Paste CSS on the left and the SCSS builds as you type.

0Rules read
0Blocks nested
0Variables
0 BOutput size
Try a sample

One component, before and after

Six rules from a pricing card, written flat because plain CSS gives you no other option. Every rule repeats the parent selector, the hover state repeats it again, and the breakpoint lives wherever the media block happens to sit in the file.

Input6 rules
.pricing-card { border: 1px solid #dfe2ec; border-radius: 12px; }
.pricing-card .plan-name { font-weight: 700; }
.pricing-card .plan-name a { color: #c6538c; text-decoration: none; }
.pricing-card .plan-name a:hover { color: #a33d70; }
.pricing-card.is-featured { border-color: #c6538c; }
@media (min-width: 768px) {.pricing-card { padding: 32px; }}
Output at depth 41 block
$color-1: #c6538c;.pricing-card {border: 1px solid #dfe2ec;border-radius: 12px;@media (min-width: 768px) {padding: 32px;}
.plan-name {font-weight: 700;a {color: $color-1;text-decoration: none;&:hover {color: #a33d70;}}}
&.is-featured {border-color: $color-1;}}

Four separate moves produced that block. Descendant selectors became nested blocks. The pseudo class and the modifier class folded onto the parent with an ampersand, because .pricing-card.is-featured targets the same element rather than a child. The brand pink appeared twice, so it got a name. And the breakpoint moved inside the block it modifies. Compile this file with Sass and the six original rules come back, in the same order, at the same specificity.

What each control changes

Nesting depth1 to 4 levels
Depth counts levels in the output, not parts in your selector. At 3 levels, a chain like #app .layout .sidebar .menu-link keeps its first two blocks and the remaining parts arrive as one selector on the third. Set it to 1 to skip nesting entirely and use the page as a formatter with variable extraction attached.
Nest media querieson by default
On, a breakpoint gets copied into every block it touches, so one @media rule holding eight selectors becomes eight small @media blocks. Sass gathers them back at the bottom of the compiled file, so behaviour holds and the raw output grows a little before gzip. Off, breakpoints stay grouped at the end of the SCSS in source order.
Variable threshold2, 3, or 4 repeats
A value needs this many appearances before it earns a name. Two is right for a hand written component sheet. Raise it on a 5,000 line file built by several people, where two matching hex codes are coincidence rather than a shared token.
Indent2 spaces, 4 spaces, tabs
Match whatever the target file already uses. Paste four space output into a two space project and the first commit reads as a whitespace rewrite with your real change buried in it.

Which values turn into variables

Automatic naming goes wrong quickly, so extraction stays narrow on purpose. Three groups qualify once they hit the repeat threshold:

What stays exactly where it is:

The names are placeholders.$color-1, $shadow-2, and $font-1 are numbered in order of appearance, nothing more. Rename them to $brand-pink or $card-shadow before the file lands in a repository. A stylesheet built on $color-4 is harder to read than the hex codes it replaced, and the rename is the one part of this migration where a person adds real meaning. Use Copy variable block to pull the declarations into a _variables.scss partial while you do it.

Nesting rewrites more than the indentation

The output is a different file, not a reformatted one. Read the diff before you commit it, with these four behaviours in mind.

Everything runs inside your browser tab, so pasting a production stylesheet uploads nothing. A 4,000 rule sheet converts in a few dozen milliseconds. Past roughly 20,000 rules the output pane, not the parser, is what starts to drag, so convert a stylesheet at a time rather than a concatenated bundle.

Where this converter stops

What comes out is valid SCSS. Idiomatic Sass is a different target, and four parts of it need a person who knows the design:

Syntax is the small half of moving a stylesheet onto Sass, and this page does that half properly. When you want to check the trade, run the result through the SCSS to CSS converter and compare the compiled output against the file you started with.

Questions from the middle of a migration

What people ask once a real stylesheet is in the left pane.

Does the SCSS compile back to my original CSS?

Rule for rule, in almost every case. Nesting and ampersand folding are pure syntax, and variables resolve at compile time to the exact values they replaced. Two things move: repeated selectors merge into one block, which shifts the position of rules that sat between them, and nested media queries are emitted per block instead of once. Compile the output and diff it against your source when the sheet leans on source order.

Where did my comments go?

The parser reads selectors, declarations, and at-rules only, so comment blocks are dropped rather than moved. Keep the original file open and paste headers and section notes back into the SCSS. This is the main reason to treat the output as a starting point instead of a finished file.

Why was my repeated 24px left alone?

Single lengths are skipped on purpose. Spacing numbers repeat everywhere for reasons that have nothing to do with each other, and naming them $value-3 through $value-9 makes a stylesheet harder to read. Colors, font stacks, and function shaped values such as shadows and gradients are the three groups that qualify.

What does a nesting depth of 3 actually give me?

Three levels of indentation in the output. A four part selector keeps two nested blocks and the leftover parts arrive together on the third line as a single selector. Depth 4 nests one step further, and depth 1 turns nesting off while keeping the formatting and the variable block.

Is my stylesheet sent to a server?

No. Parsing, nesting, variable extraction, and the clipboard write all run in JavaScript inside your tab. Nothing is uploaded and nothing is stored between visits, so a stylesheet from a client project is safe to paste.

Should I nest breakpoints or keep them at the bottom?

Nest them while you are actively editing a component, since reading a padding and its override in the same block beats scrolling. Keep them grouped when several components share one breakpoint and you tune that breakpoint as a unit. The switch is there because both habits are defensible.

Can it output the indented .sass syntax instead?

Not from here. This page writes SCSS with braces and semicolons, which is what most projects use. For the brace free indented syntax, run the SCSS through the SCSS to Sass converter as a second step.