Syntax: SCSS vs. Sass

This section documents Sass/SCSS as implemented by Dart Sass, the current official and actively maintained compiler — it is not tied to any specific book, build tool, or CSS framework (Bootstrap, Bulma, etc.). Unlike the other reference sections on this site, no single reference book underpins it: the content was generated with the assistance of AI from general knowledge of Dart Sass, and should be verified against the current official documentation at sass-lang.com before relying on it in production. Sass continues to evolve, so behaviour described here may lag the compiler you are actually running.

This section’s bibliography lists the reference material consulted while preparing these pages.

Sass is a CSS preprocessor: a language that adds variables, nesting, mixins, functions, and a module system on top of CSS, then compiles down to the plain CSS a browser actually understands (see Compilation). What makes it slightly unusual among preprocessors is that it offers two different syntaxes for the same language. Both are handled by the same compiler, expose exactly the same features, and produce exactly the same CSS — they differ only in punctuation.

The two syntaxes

SCSS Indented Sass

File extension

.scss

.sass

Blocks

Curly braces { }

Indentation

Statement terminator

Semicolon ;

Newline

Relationship to CSS

A strict superset — any valid CSS file is a valid SCSS file

Not CSS-compatible — plain CSS must be converted first

Typical use

The default choice, and by far the most common in practice

Niche; favoured by those who prefer terse, whitespace-driven syntax

SCSS: the default

SCSS ("Sassy CSS") is the syntax you should reach for unless you have a specific reason not to. Because it is a superset of CSS, you can rename an existing .css file to .scss and it will compile unchanged, then adopt Sass features incrementally. Every example elsewhere in this section uses SCSS.

@use "sass:color";

$primary: #3f51b5;
$radius: 4px;

@mixin button-base {
  border: 0;
  border-radius: $radius;
  cursor: pointer;
}

.card {
  padding: 1rem;
  border-radius: $radius;

  .card__title {
    margin: 0;
    color: $primary;
  }

  .card__button {
    @include button-base;
    background: $primary;
    color: white;

    &:hover {
      background: color.adjust($primary, $lightness: -10%);
    }
  }
}

The indented syntax

The indented syntax — the original one, and the reason the language is called "Sass" — drops braces and semicolons entirely, deriving block structure from indentation the way Python or YAML does. Here is the exact same stylesheet:

@use "sass:color"

$primary: #3f51b5
$radius: 4px

@mixin button-base
  border: 0
  border-radius: $radius
  cursor: pointer

.card
  padding: 1rem
  border-radius: $radius

  .card__title
    margin: 0
    color: $primary

  .card__button
    @include button-base
    background: $primary
    color: white

    &:hover
      background: color.adjust($primary, $lightness: -10%)

Both files compile to identical CSS:

.card {
  padding: 1rem;
  border-radius: 4px;
}
.card .card__title {
  margin: 0;
  color: #3f51b5;
}
.card .card__button {
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  background: #3f51b5;
  color: white;
}
.card .card__button:hover {
  background: rgb(19.5419479267%, 25.1253616201%, 56.1443265831%);
}

That hover value looks odd printed as a percentage rgb() rather than a hex code, but it’s the same colour (#32408f) — current Dart Sass’s colour engine represents the output of a colour function like color.adjust() in this form rather than re-serializing it back to hex.

The indented syntax is consistent about its terseness: multi-line expressions must be escaped or kept on one line, and a few constructs (such as inline comments) are written differently. Indentation must also be consistent within a file — mixing tabs and spaces is an error.

Which one to choose

Prefer SCSS. It is the default in essentially every toolchain, it is what published Sass libraries and framework source (Bootstrap, Bulma) are written in, it is what almost all documentation and answers online use, and its CSS-superset property means there is no translation step when copying a snippet out of a browser’s developer tools or a CSS reference. The indented syntax remains fully supported and is not deprecated — it is simply a stylistic preference, and choosing it costs you nothing in features but some convenience.

The two syntaxes can coexist in one project: a .scss file may @use a .sass partial and vice versa, since the distinction is purely at the parsing stage. Dart Sass also ships a sass-convert-style migration path through the community sass-migrator tool for translating between them wholesale.

Comments

Comment syntax is one place worth calling out, because Sass adds a form CSS doesn’t have:

/* A standard CSS comment. This is preserved in the compiled output
   (except in compressed mode). */

// A Sass single-line comment. This is stripped from the output entirely.

/*! A loud comment. Preserved even in compressed output -- useful for licence banners. */

Silent // comments are the right default for notes meant for whoever is reading the Sass source, since they add nothing to the bytes shipped to the browser.