CSS Tools
CSS to SCSS / Sass Converter
Plain CSS into Sass — brace-and-semicolon SCSS or the indented .sass syntax, chosen with one toggle.
In short
Convert CSS to SCSS or to Sass's indented syntax with one toggle: nesting rebuilt, braces and semicolons handled for you, custom properties left alone.
By NaveenKumar T · Updated
Learn: Sass vs SCSS vs LESS vs Stylus: Choosing a CSS Preprocessor
- SCSS or indented Sass output
- Nesting preserved
- Media queries preserved
Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →
Example
CSS to SCSS / Sass: input and output
A product grid driven by two custom properties, with native child-combinator nesting and two breakpoints that only override the tokens.
/* Responsive product grid */
.grid {
--columns: 4;
--gutter: 1.5rem;
display: grid;
grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
gap: var(--gutter);
& > .card { grid-column: span 1; }
& > .card.featured { grid-column: span 2; }
&:empty { display: none; }
@media (max-width: 1024px) { --columns: 2; }
@media (max-width: 640px) { --columns: 1; --gutter: 1rem; }
}.grid {
--columns: 4;
--gutter: 1.5rem;
display: grid;
grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
gap: var(--gutter);
& > .card {
grid-column: span 1;
}
& > .card.featured {
grid-column: span 2;
}
&:empty {
display: none;
}
@media (max-width: 1024px) {
--columns: 2;
}
@media (max-width: 640px) {
--columns: 1;
--gutter: 1rem;
}
}
The --columns and --gutter tokens stay custom properties, inside the @media blocks too — the converter never rewrites them as $variables — while the & > .card rules become ordinary SCSS nesting and the leading comment is dropped. Flip the toggle to Sass (indented) and the same tree comes back without braces or semicolons.
Learn more
One converter, two Sass syntaxes
Sass ships two spellings of the same language. SCSS keeps CSS's braces and semicolons, which makes every valid CSS file a valid SCSS file — so converting to SCSS is structurally lossless, a pure syntax upgrade rather than a rewrite. The indented syntax, the .sass extension, drops braces and semicolons entirely and carries structure in whitespace; it is older, terser, and still standard in a long tail of Rails and Vue codebases.
The Output syntax toggle picks between them, and nothing else about the conversion changes. Selector lists, attribute selectors, pseudo-classes and pseudo-elements, at-rules, custom properties and multi-part values are copied through verbatim in both modes; only the punctuation and the line structure differ. Both feed the same dart-sass compiler, so a file converted either way behaves identically once built.
What converts, and what deliberately does not
What converts: rule structure. Native CSS nesting becomes Sass nesting, & parent references are kept exactly as written because Sass reads them the same way, selector lists stay grouped, and an @media or @supports block nested inside a rule stays nested inside it. The conversion runs on a parsed rule tree rather than a find-and-replace, which is why nesting depth and comma-separated selector groups survive intact.
What does not convert, on purpose: custom properties are never turned into $variables, and no value is rewritten — colours are not shortened, units are not changed, nothing is reordered. What is lost is cosmetic rather than semantic: comments and blank lines are stripped during parsing, and indentation is normalised. Run the result through the SCSS formatter if your repo enforces a particular prettier configuration.
Adopting Sass without a big-bang rewrite
This is the on-ramp conversion. A project decides to adopt Sass and the existing stylesheets need to become modules without anything breaking; because the conversion is structurally lossless, you can rename and convert file by file inside the same pull request that adds the build step, then pull repeated colours and sizes into tokens gradually. The diff stays reviewable at every stage, which is the difference between a migration that lands and one that stalls in review.
The same problem arrives from the other side long after adoption: plain CSS keeps showing up — from prototypes, vendor snippets, a designer's handoff, a DevTools copy — and it has to match the codebase's dialect before it can be committed. Teams on the indented syntax face exactly this, which is why the Sass output exists here rather than on a separate page. When you need the reverse trip, SCSS / Sass to CSS compiles with dart-sass, SCSS ⇄ Sass switches between the two Sass syntaxes, and the CSS preprocessor converter covers LESS and Stylus.
Help
Frequently asked questions
Everything you need to know about the CSS to SCSS / Sass.
01How do I convert CSS to SCSS?
Paste your CSS (or load a file), choose the output syntax — SCSS for the brace-and-semicolon style, Sass for the indented one — and press Convert. The sheet is parsed into a rule tree and re-emitted in the dialect you picked, ready to copy or download as .scss or .sass.
02Should I nest everything once it is converted?
Resist the urge. Converting gives you a valid Sass file, not a refactored one, and that is the right starting point: deep nesting produces over-specific selectors that are hard to override and hard to delete. Nest where structure genuinely repeats — a component block, its BEM children, pseudo-classes via & — and leave the rest flat. The same applies to $variables: extract the colours and sizes that repeat, not every literal.
03Can I get the indented Sass syntax instead?
Yes — that is what the Output syntax toggle is for. Switch it to Sass (indented) and the same conversion drops every brace and semicolon, expresses each block by two-space indentation and puts one declaration per line, which is the .sass file extension's syntax. Nothing about the language changes: both syntaxes compile with dart-sass and support the same variables, mixins, functions and modules, so the choice is purely your codebase's house style. One-line rules necessarily become several lines, because indented syntax has no braces to keep them on one.
04Will my custom properties become $variables?
No, and that is deliberate. A --columns custom property stays a custom property — including where it is re-declared inside a nested @media block — and every var(--columns) call is untouched. Custom properties cascade and can be changed at runtime; $variables are resolved once at compile time and vanish. Swapping one for the other would silently change how the sheet behaves, so the converter never does it. Introduce $variables yourself, for the values that genuinely are compile-time constants.
05What happens to native CSS nesting and comments?
Native nesting is where this conversion earns its keep: & > .card, &:hover, &[aria-current="page"] and @media blocks written inside a rule all map one-to-one onto Sass nesting, at any depth, with selector lists cross-multiplied correctly. Comments do not survive — the parser strips /* */ and // before building the rule tree — so re-add licence headers afterwards. Blank lines are not preserved either, and indentation is normalised to your chosen width.
Keep working