CSSSass / SCSS Introduction

Sass / SCSS Introduction

Sass (Syntactically Awesome StyleSheets) is a CSS preprocessor: a language that extends CSS with features like variables, nesting, mixins, and functions, and then compiles down to plain CSS before it ever reaches a browser. The browser never sees Sass — it only ever sees the ordinary CSS that a compiler step produced from it.

Two syntaxes, one language
Sass actually supports two different syntaxes for writing the same underlying language. The original, indented syntax (files ending in .sass) drops curly braces and semicolons in favor of significant whitespace, similar in spirit to Python:

SCSS
// Indented Sass syntax (.sass) — no braces, no semicolons
.card
  padding: 1rem
  border-radius: 8px

  .card-title
    font-weight: 600
SCSS (Sassy CSS, files ending in .scss) is a superset of ordinary CSS syntax — braces and semicolons included — which means any valid plain CSS file is already valid SCSS. This is the syntax that dominates in practice today:

SCSS
// SCSS syntax (.scss) — CSS-like braces and semicolons
.card {
  padding: 1rem;
  border-radius: 8px;

  .card-title {
    font-weight: 600;
  }
}
"Sass" usually means SCSS in practice
When developers today say "we use Sass," they almost always mean the .scss syntax, not the older indented .sass syntax. The rest of this Sass series on this site uses SCSS exclusively, since that's what you'll encounter in the overwhelming majority of real codebases, tutorials, and framework source code.
Why Sass existed in the first place

Sass was created in 2006, at a time when plain CSS had no variables, no nesting, no way to define a reusable block of declarations, and no way to compute a value from another value. Every large stylesheet ended up full of repeated color codes, repeated spacing values, and repeated selector prefixes with no way to abstract any of it. Sass filled exactly those gaps.

Gap in old CSS

Sass feature that filled it

No variables

$variable: value;

No nesting

Nested selector blocks with &

No reusable declaration blocks

@mixin / @include

No computed values

@function

No sharing across files without one giant file

@import (now @use / @forward)

Much of this gap has since closed in native CSS
This is a genuinely evolving landscape. Native CSS now has custom properties (a real, if different, answer to variables — see CSS Custom Properties), native CSS Nesting, and modern color functions. Sass remains extremely popular, but it is no longer solving problems plain CSS has no answer to at all — the calculus for adopting it on a brand-new project is more nuanced than it was a decade ago.
Installing and compiling Sass

Sass needs a compile step somewhere in your toolchain. The most common path today is the Dart Sass command-line tool, installed via npm, either run directly or wired into a bundler (Vite, webpack, or a framework's built-in Sass support).

Bash
# Install Dart Sass as a dev dependency
npm install --save-dev sass

# Compile once
npx sass styles.scss styles.css

# Watch for changes during development
npx sass --watch styles.scss:styles.css
Most real projects never run this by hand — a framework or bundler config (webpack's sass-loader, Vite's built-in Sass support, or Next.js's built-in Sass support) handles compilation automatically as part of the normal build.
Where this series goes next
Related pages
See PostCSS and Less Overview for how Sass compares to the other major preprocessing tools in the ecosystem.