FormatterHQ

Online Sass Compiler for the Indented Syntax

An online Sass compiler for learning and testing the indented syntax: write rules without braces, watch Dart Sass compile them live, and catch indentation mistakes early.

Input SASS
Output CSS
Ready.

How to use the SASS Compiler

  1. Type indented Sass into the Input editor, or press Sample to load an example.
  2. Indent each nested level by the same number of spaces; the CSS recompiles as you type.
  3. Read any error in the status bar and fix the highlighted line.
  4. Check the output for rules or properties you did not expect, a sign of an indentation slip.
  5. Tick Minify output if you want compressed CSS, then copy or download it.

An online Sass compiler for learning the indented syntax

The indented syntax is Sass without braces: indentation shows nesting and a line break ends a declaration. It is quick to write once you know its rules, and easy to get subtly wrong before you do. This online Sass compiler runs Dart Sass 1.x on every edit, so you can see how each indent changes the CSS and learn the syntax by experimenting.

Compiling complete .sass files for a project? SASS to CSS uses the same compiler with expanded output and no options. This page adds Minify output and concentrates on the syntax itself. If you write braces and semicolons, the SCSS compiler is the right place.

Shorthand you can try

=button($bg: #0f766e)
  background: $bg
  color: white
  &:hover
    opacity: .9

.save
  +button
.delete
  +button(#b91c1c)
.save {
  background: #0f766e;
  color: white;
}
.save:hover {
  opacity: 0.9;
}

.delete {
  background: #b91c1c;
  color: white;
}
.delete:hover {
  opacity: 0.9;
}

=name defines a mixin and +name includes it. The long forms @mixin and @include work too, so you can switch between them while learning. Arguments with defaults behave exactly as in SCSS: +button used the default color, while +button(#b91c1c) replaced it. Note how the nested &:hover inside the mixin produced a separate rule for each class that included it.

Nested properties

A property that ends in a colon can hold sub-properties on the following, deeper-indented lines:

$gap: 8px
.card
  padding: $gap * 2
  &__title
    margin:
      bottom: $gap
  .dark &
    background: #111
.card {
  padding: 16px;
}
.card__title {
  margin-bottom: 8px;
}
.dark .card {
  background: #111;
}

This feature explains one of the traps below: an extra space can accidentally turn a line into a sub-property.

Indentation traps that do not raise errors

Some mistakes compile without complaint and simply produce different CSS. Each of these was run through this compiler.

One space too many

.a
  color: red
   width: 10px
.a {
  color: red;
  color-width: 10px;
}

The extra space nested width under color as a sub-property.

A missing colon

.a
  color red

This produces no CSS at all. Without a colon, the line reads as a nested selector with an empty body.

A missing indent

nav
  a
  color: red
nav {
  color: red;
}

color sits at the same level as a, so it belongs to nav, and the empty a rule vanishes.

After every change, check that the CSS contains the selectors and properties you intended. The live output makes this a habit rather than a chore. A reliable routine is to count the rules: if you wrote three selectors and see two, look for a line that lost or gained an indent. Most editors can show whitespace characters, which makes stray spaces and tabs visible at a glance.

Errors the compiler does report

  • Expected tabs, was spaces. The file started indenting with tabs and a later line uses spaces (or the other way round). Pick one.
  • Expected newline. Usually a brace copied from SCSS or CSS, such as .a {.
  • expected selector. A line like width 10px after a declaration; add the missing colon.
  • Undefined variable. or Undefined mixin. A typo, or a definition from a file you did not paste.

Each message includes the line and column, and the line is highlighted in the editor. Trailing semicolons, by contrast, are tolerated by the Dart Sass version used here, although they are unnecessary in the indented syntax.

Loops and modules work the same

Everything else in Sass carries over unchanged. A quick loop shows the indentation-only style:

@use 'sass:math'
$cols: 4
@for $i from 1 through $cols
  .w-#{$i}
    width: math.percentage(math.div($i, $cols))

This compiles to four classes, .w-1 to .w-4, with widths of 25%, 50%, 75% and 100%. Built-in modules load normally; your own partials cannot, because the compiler has no access to your files.

Moving between syntaxes

To see the compiled styles written as SCSS, use SASS to SCSS; for the reverse direction there is SCSS to SASS. Both go through CSS, so variables and mixins end up as plain values. Compilation runs in your browser.

Frequently asked questions

Why does my output contain a property like color-width?
A line was indented one level deeper than its siblings, so Sass treated it as a nested sub-property of the line above. Align it with the other declarations.
Why does a rule produce no CSS at all?
A declaration written without a colon, such as color red, is read as a nested selector with no body. Add the colon: color: red.
Can I mix tabs and spaces?
No. Dart Sass reports Expected tabs, was spaces (or the reverse) at the first line that switches. Use one kind of indentation throughout.
Are semicolons an error in the indented syntax?
Not in the Dart Sass version used here: trailing semicolons are accepted. Braces are not and cause an Expected newline error.
Is this the same compiler as SASS to CSS?
Yes, both use Dart Sass. This page adds Minify output and focuses on learning the syntax; SASS to CSS always prints expanded CSS.

Last updated October 3, 2026

Related tools