SCSS to CSS Converter

Free toolNo sign-up
SCSS Input
Examples:
CSS Output
Paste an SCSS block on the leftor click an example — it converts live as you type
Supports:nesting & parent ref$vars inline or var(--)@media nestedmath same-unit

About this tool

Paste any SCSS block on the left — nested rules with the & parent reference, $variables, nested @media queries, same-unit math — and get plain CSS on the right. Live conversion as you type, toggle between inline-value or CSS custom-property variable modes, copy the output in one click. No build step, no npm install, no server round-trip — the compiler runs entirely in your browser. Handles the SCSS feature set that ~90% of real-world snippets use; unsupported features (mixins, @extend, color functions, control directives) surface as amber warnings so you know what to hand-audit.

?

Why an SCSS → CSS converter

🎯
One-paste conversion, no build step
Paste an SCSS snippet — from a tutorial, a codebase you're migrating away from Sass, a Stack Overflow answer — and get plain CSS in the same window. No `npm install sass`, no Gulp/Webpack loader, no watcher process. Useful for the 5-minute case where firing up a real build feels absurd.
🌀
Real nesting resolution — including `&`
The `&` parent-reference is the SCSS feature almost every "just use plain CSS" recommendation trips on. This tool flattens correctly: `.foo { &:hover { .bar { } } }` becomes `.foo:hover .bar { }`, matching how Sass compiles it. Comma-separated parents expand cartesian too.
🎨
$variables → your choice: inline or CSS custom properties
"Inline values" mode substitutes `$brand` with its literal value everywhere used — matches Sass's default behavior, produces the smallest CSS. "CSS variables" mode preserves them as `--brand` on `:root` so the output stays runtime-themeable. Toggle in the output header depending on whether you want static CSS or a theming layer.
Same-unit math evaluated in-place
`padding: 12px + 4px` becomes `padding: 16px`. Handles `px`, `em`, `rem`, `%`, `vw`, `vh`. Mixed-unit expressions (`10px + 2em`) are left unchanged — real Sass errors on those anyway, so this matches expected behavior.

How to use this converter

01
Paste your SCSS on the left
Any SCSS block — nested rules, variables, @media queries, block comments. The output panel updates live as you type. Try one of the preset examples if you want to see how a specific SCSS feature converts.
02
Pick a variable-handling mode
"Inline values" (default) substitutes every $var with its value directly into the CSS — smallest output, matches Sass's default compile. "CSS variables" instead emits :root { --var: value } and references it as var(--var) — preserves runtime theming ability.
03
Check the notes strip (if it appears)
Amber warnings appear at the bottom of the output panel when the tool skips unsupported SCSS features (@mixin, @include, @extend, @import, control directives like @if / @each). The output CSS is still valid; you just need a real Sass compiler for those specific features.
04
Copy the output
Click Copy in the output header. Paste into your CSS file, design token layer, or PR. Works well as a first-pass migration step: convert SCSS to CSS, then hand-audit the result against a real Sass build if the file uses advanced features.

Conversion examples

Nesting + & parent
/* Input */
.card {
  padding: 1rem;
  border-radius: 8px;

  &:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  }

  .title {
    font-size: 1.25rem;
    font-weight: 600;
  }
}

/* Output */
.card {
  padding: 1rem;
  border-radius: 8px;
}
.card:hover {
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.card .title {
  font-size: 1.25rem;
  font-weight: 600;
}
Variables — inline
/* Input */
$brand: #7c3aed;
$radius: 8px;

.button {
  background: $brand;
  border-radius: $radius;
  color: white;
}

.link { color: $brand }

/* Output — "Inline values" mode */
.button {
  background: #7c3aed;
  border-radius: 8px;
  color: white;
}
.link {
  color: #7c3aed;
}
Variables — CSS vars
/* Same input, "CSS variables" mode */

:root {
  --brand: #7c3aed;
  --radius: 8px;
}

.button {
  background: var(--brand);
  border-radius: var(--radius);
  color: white;
}
.link {
  color: var(--brand);
}

/* Now the palette is runtime-themeable
   via document.documentElement.style.setProperty(). */
Nested @media
/* Input — nested @media */
.container {
  padding: 1rem;

  @media (min-width: 768px) {
    padding: 2rem;
    max-width: 720px;
  }
}

/* Output */
.container {
  padding: 1rem;
}
@media (min-width: 768px) {
  .container {
    padding: 2rem;
    max-width: 720px;
  }
}

Pro tips (and the sharp edges)

01
The tool handles what tutorials teach — not the whole Sass surface
Nesting, $vars, @media queries, same-unit math, block comments, line comments. NOT handled: @mixin/@include (needs argument binding + @content), @extend (needs multi-selector chain resolution), @use/@forward (needs file-tree resolution), Sass color functions (lighten / darken / mix), and control directives (@if / @each / @for / @function). If your SCSS uses those, the notes strip flags them and you'll need a real Sass compiler for the final pass.
02
Prefer "CSS variables" mode when migrating for the long term
Inline mode locks values into the output — great for one-off snippets. Custom-properties mode keeps the theming ability that made you use $vars in the first place, and CSS custom properties are baseline everywhere as of 2020. If you're migrating a codebase off Sass, "CSS variables" is usually the right choice; if you're just converting a code snippet for a blog post, "inline" reads cleaner.
03
The `&` parent reference is where most manual conversions break
Devs manually converting SCSS often flatten `.foo { &:hover { } }` to `.foo :hover { }` (with a space) — which selects hovered descendants, not the hovered element itself. This tool catches that: no-space concatenation for pseudo-classes/elements, space-separated for descendant combinators. Same rule Sass uses.
04
Block comments survive, line comments don't
SCSS supports `// line comments` that don't exist in CSS — the tool strips them (they'd be a parse error in the browser). Block comments `/* … */` are valid CSS, so they pass through unchanged and stay attached to the right rule.
05
Nested @media queries are hoisted, not left inside
When you write `.foo { @media (min-width: 768px) { color: red } }`, Sass hoists the @media to the top level as `@media (min-width: 768px) { .foo { color: red } }`. This tool does the same — nesting an @media inside a rule is the whole point of writing it that way, and the output is what real Sass would emit.
?

Frequently asked questions

01

Which SCSS features does this converter handle — and which does it skip?

The tool handles the SCSS feature set that ~90% of real-world SCSS snippets use: nesting (with correct & parent-reference flattening), $variables (with inline substitution OR CSS custom-property emission), nested @media queries (correctly hoisted to top level), same-unit math (12px + 4px → 16px), block comments (preserved as valid CSS), and line comments (// stripped since they'd be invalid CSS). Skipped (because they require a real Sass compiler with file-tree access + control-flow evaluation): @mixin/@include (needs argument binding + @content block resolution), @extend (multi-selector chain expansion), @import/@use/@forward (partial-file resolution — the browser can't read your project tree), Sass color functions (lighten(), darken(), mix(), adjust-hue()), control directives (@if/@each/@for/@function). When any unsupported feature appears in your input, the tool emits an amber warning listing exactly which feature was skipped so you know what to hand-audit. For those cases: install real Sass (npm install -D sass) and run a proper compile.

02

Should I convert my SCSS to plain CSS, or migrate to CSS custom properties?

Depends on why you're doing the conversion. Inline values mode (default) is right when you're converting a snippet from a tutorial, Stack Overflow answer, or design-system doc for immediate use — smallest output, no runtime cost, matches how Sass compiles by default. CSS variables mode is right when you're actually MIGRATING off Sass at codebase scale. CSS custom properties have been Baseline browser-supported since 2020 (Chrome 49, Safari 9.1, Firefox 31 — literally every browser except IE11), and unlike Sass $variables they can be updated at runtime, inherited through the cascade, and swapped by adding/removing classes on <html> — which is what makes light/dark themes and per-brand palettes trivial. If your codebase is using Sass primarily for the $brand/$radius/$spacing token layer, custom-properties mode gives you the migration path where you keep the theming pattern but drop the build step. Vercel, Linear, GitHub, and Stripe all migrated design systems from Sass tokens to CSS custom properties for exactly this reason.

03

How does nesting flatten — especially with the & parent reference?

The tool follows Sass's exact rules for nesting resolution. Given .card { &:hover { color: red } }, the & gets replaced with the parent selector before flattening: output is .card:hover { color: red } (no space — the ampersand concatenates directly). Contrast with .card { :hover { color: red } } (no ampersand): output is .card :hover { color: red } (WITH space — selects hovered descendants, not the card itself). This is the #1 place manual SCSS→CSS conversions break: devs write &:hover in SCSS but manually convert to .card :hover, which changes the selector meaning entirely. The tool handles the concatenation rules correctly. Comma-separated parents expand cartesian: .a, .b { & > c { } } becomes .a > c, .b > c { }. Deep nesting works recursively — .a { .b { .c { &:hover { } } } } becomes .a .b .c:hover { }. Every rule Sass docs cover is implemented; if you spot a case where the output diverges, that's a bug worth reporting.

04

Are nested @media queries actually valid to write inside a rule?

In SCSS, yes. In vanilla CSS, actually YES now too — CSS Nesting (Baseline 2024, Chrome 120+, Safari 17.4+, Firefox 117+) allows nesting including @media queries inside rules. But if you're supporting older browsers or converting for a bundle that has to work on 2022-era Safari, you want the flattened output: the SCSS pattern .container { @media (min-width: 768px) { padding: 2rem } } becomes .container { } @media (min-width: 768px) { .container { padding: 2rem } } in the output. The tool always hoists nested @media to the top level — matches how real Sass compiles it, and produces CSS that works everywhere without requiring the CSS Nesting spec. If you want the modern flat-nested CSS output instead (skipping the hoist), that's what real Sass does when you use @included nesting or when you write CSS nesting directly — but this converter treats @media the traditional Sass way.

05

What's the difference between this and installing Sass locally with `npm install -D sass`?

Scope. Real Sass (npm install -D sass or Dart Sass via sass-embedded) is a full compiler with file-tree resolution (@import 'partials/typography' reading actual files), function definitions (@function multiply($a, $b) { @return $a * $b }), mixin argument binding with defaults (@mixin card($radius: 8px)), the full color-function library (lighten($brand, 10%), mix($a, $b, 40%)), control flow (@each $color in $palette), and the full @use/@forward module system. This tool handles the SUBSET of SCSS you can compile deterministically in-browser without file-system access — nesting + variables + @media + math + basic @extend. That covers the vast majority of code snippets you'd paste from a tutorial or a legacy file; it doesn't cover a real Sass codebase's build. Rule of thumb: if the SCSS you're converting fits in a code-block on a docs page, this tool works. If it's a multi-file project with partials + mixins + color functions, install real Sass.

06

Can I use this converter offline / does it send my code anywhere?

Zero network. The SCSS → CSS conversion runs entirely in your browser via inline JavaScript — no server call, no API upload, no telemetry on the code content. The site itself uses Google Analytics for pageview counts and Mediavine for ads (both standard, both toggleable via browser extensions), but neither ever sees the SCSS or CSS text you paste into the converter. Safe for confidential design tokens, unreleased branding colors, internal-tool CSS. If you want to work fully offline, save the /tools/scss-to-css-converter/ page for offline (Chrome: three-dot menu → Save page as → Complete webpage) — the converter still works because the JavaScript is bundled into the HTML.

Search CodeFronts

Loading…