FormatterHQ

Online SCSS Compiler and Playground

An online SCSS compiler for experiments: write a function, a mixin or a loop, watch Dart Sass recompile as you type, and jump straight to errors reported by line and column.

Input SCSS
Output CSS
Ready.

How to use the SCSS Compiler

  1. Write or paste an SCSS snippet into the Input editor, or press Sample.
  2. Let the output recompile as you type, or press Compile.
  3. When the status bar shows an error, go to the highlighted line and the column given in the message.
  4. Switch on Minify output to compare expanded and compressed CSS.
  5. Copy or download the CSS once the snippet does what you want.

An online SCSS compiler built for experimenting

Sass rewards trying things out: a function that converts pixels to rem, a breakpoint mixin with @content, a map-driven loop. This online SCSS compiler runs Dart Sass 1.x in your browser and recompiles on every edit, so you see immediately what each change produces. Errors name the line and column, and the line is highlighted in the editor.

Turning finished stylesheets into CSS for a project? SCSS to CSS uses the same Dart Sass build with expanded output and no options. This page adds Minify output and focuses on learning and debugging.

Three snippets to try

Each example below shows real output from this compiler. Paste one in, then change an argument, a selector or a unit and watch how the CSS reacts. Breaking a snippet on purpose is useful too: it shows you the exact message Dart Sass prints for that mistake.

A function

@use 'sass:math';
@function rem($px, $base: 16px) {
  @return math.div($px, $base) * 1rem;
}
.title { font-size: rem(24px); margin-bottom: rem(8px); }
.title {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;
}

Change $base in a call, for example rem(24px, 12px), and the output follows. Built-in modules such as sass:math, sass:map and sass:color load without any files.

A mixin with @content and keyword arguments

@mixin respond($bp) {
  @media (min-width: $bp) { @content; }
}
.card {
  padding: 8px;
  @include respond(768px) { padding: 16px; }
}
.card {
  padding: 8px;
}
@media (min-width: 768px) {
  .card {
    padding: 16px;
  }
}

The block passed to the mixin lands where @content sits, and the media query moves outside the rule with .card repeated inside. Arguments can also be passed by name in any order: @include theme($fg: black, $bg: #fde68a) fills each parameter by its name.

The parent selector

.card {
  &__title { font-weight: 600; }
  &--wide { max-width: none; }
  .dark & { background: #111; }
}
.card__title {
  font-weight: 600;
}
.card--wide {
  max-width: none;
}
.dark .card {
  background: #111;
}

& can be a prefix for BEM-style names or placed after another selector to style the component inside a themed container.

Maps and loops

$sizes: (sm: 4px, md: 8px);
@each $k, $v in $sizes {
  .p-#{$k} { padding: $v; }
}
.p-sm {
  padding: 4px;
}

.p-md {
  padding: 8px;
}

Add a third entry such as lg: 16px to the map and a new class appears. Loops like this generate whole sets of utility classes, so checking their output in a playground before adding them to a project helps keep the CSS small. Dart Sass separates rules produced at the top level by a loop with a blank line, which is only formatting.

Error messages you will meet

Each message ends with the position Dart Sass reports. These come straight from the compiler:

MessageWhat to check
Undefined variable. (line 2, column 10)Spelling, and whether the variable is declared above this line or inside another block
expected ";". (line 3, column 8)The line before the reported one: its declaration has no semicolon
10px and 2em have incompatible units.Arithmetic mixing absolute and relative units; use calc()
Undefined mixin.A misspelled name, or a mixin that lives in another file
The target selector was not found.An @extend of a selector that does not exist; add !optional if that is intended
Can't find stylesheet to import.An @use or @import of your own file, which the browser cannot read

Note the second row: Dart Sass notices a missing semicolon only when it reaches the next line, so the position points one line late.

Inspecting values without @debug

This compiler accepts @debug and @warn but does not display their messages. Two workarounds help when you want to see a value. Print it into a custom property with interpolation:

@use 'sass:math';
$ratio: math.div(16px, 3);
.probe { --debug: #{$ratio}; }
.probe {
  --debug: 5.3333333333px;
}

Or stop compilation on purpose with @error "value: #{$x}"; the message appears in the status bar with the position of the call that triggered it.

Where to go next

Prefer the indented syntax? Try the same experiments in the Sass compiler. To tidy the SCSS source itself, use the SCSS Formatter, and to start from existing CSS, CSS to SCSS nests it for you. Compilation stays in your browser.

Frequently asked questions

Which Sass version runs in this playground?
The Dart Sass JavaScript package, version 1.x, the implementation maintained by the Sass team. Deprecation warnings for older features are silenced.
Why does the error point to the line after my mistake?
A missing semicolon is only detected when the parser reaches the next line, so the reported position is where parsing failed, not where the semicolon belongs.
Why do @debug messages not appear?
The compiler discards @debug and @warn output. Interpolate the value into a custom property, or use @error to stop and print it.
Can I load my own partials with @use?
No. Only built-in modules such as sass:math load here. Paste the partial's contents above the code that needs it.
Is this the same engine as SCSS to CSS?
Yes. Both use Dart Sass; this page adds Minify output and is aimed at testing snippets, while SCSS to CSS always prints expanded CSS.

Last updated September 27, 2026

Related tools