What Is Sass? SCSS Explained for CSS Developers

What Sass Actually Is
Sass is a CSS preprocessor: a tool that lets you write stylesheets in a more powerful language, then compiles them down to plain CSS the browser can read. You get features CSS historically lacked — variables, nesting, reusable chunks of styles, math, loops, and file splitting — and a compiler turns all of it into a regular .css file. The browser never sees your Sass. It only ever sees the compiled CSS output.
The name stands for Syntactically Awesome Style Sheets. When people say "Sass" in casual conversation they usually mean the whole tool and language. When they say SCSS, they mean the specific, CSS-like syntax most projects actually write (more on that distinction below). Sass has been around since 2006 and is the most widely used CSS preprocessor by a wide margin — it ships baked into countless design systems, component libraries, and framework build tools.
Here is the core idea in one comparison. This SCSS:
@use 'sass:color';
$brand: #2d6cdf;
.button {
background: $brand;
&:hover {
background: color.adjust($brand, $lightness: -10%);
}
}
compiles to this CSS:
.button {
background: #2d6cdf;
}
.button:hover {
background: #1d55bc;
}
You wrote the color once and nested the hover state inside the button. The compiler expanded it into the flat, repetitive CSS the browser expects. Note the color.adjust() call from the built-in sass:color module — it shifts the color's lightness down by 10 points. You may still see the older darken($brand, 10%) in tutorials, but that legacy color function is being phased out of Dart Sass (it emits deprecation warnings and is slated for removal in Dart Sass 2.0), so reach for color.adjust() or color.scale() in new code.
Sass vs SCSS: The Two Syntaxes
This trips up almost everyone new to Sass. "Sass" refers to two things at once: the overall tool, and one of its two syntaxes.
SCSS syntax (.scss) |
Indented syntax (.sass) |
|
|---|---|---|
| Looks like | Regular CSS, with extras | Terse, no braces or semicolons |
Braces { } |
Yes | No — uses indentation |
| Semicolons | Yes | No — uses line breaks |
| Superset of CSS | Yes — any valid CSS is valid SCSS | No |
| Popularity | Dominant, used almost everywhere | Rare |
Here is the same rule in both. SCSS:
.card {
padding: 1rem;
color: #333;
}
Indented .sass:
.card
padding: 1rem
color: #333
Use SCSS. It's a superset of CSS, which means you can rename any .css file to .scss and it just works, then adopt Sass features gradually. That single fact is why the industry standardized on it. The rest of this guide, and virtually every tutorial you'll read, uses SCSS syntax. We break the differences down further in Sass vs SCSS.
Why Developers Use Sass
Plain CSS has improved a lot, but Sass still solves real maintenance problems on medium and large stylesheets. Here's what you actually get.
Variables
Define a value once, reuse it everywhere. Change your brand color or spacing scale in one place instead of hunting through thousands of lines.
$space: 8px;
$radius: 6px;
.panel {
padding: $space * 2;
border-radius: $radius;
}
Nesting
Write selectors inside their parent to mirror your HTML structure. The & refers to the parent selector, which is perfect for states and modifiers.
.nav {
display: flex;
a {
color: inherit;
&.is-active {
font-weight: 700;
}
}
}
A word of caution: deep nesting is the most common Sass mistake. Every level you nest adds specificity and length to the compiled selector. Keep it to two or three levels.
Mixins and functions
A mixin is a reusable block of declarations you pull in with @include. A function computes and returns a single value with @return. Mixins output styles; functions output values.
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.modal {
@include flex-center;
}
Mixins can take arguments too, which makes them ideal for things like consistent media queries or button variants. We cover the split in depth in Sass mixins vs functions.
Partials and file splitting
Break your stylesheet into small files (called partials, named with a leading underscore like _buttons.scss) and pull them together. Modern Sass uses @use for this:
// main.scss
@use 'reset';
@use 'buttons';
@use 'layout';
Everything compiles into a single CSS file, so splitting your source costs you nothing at runtime. Note that @use is the current standard — the older @import rule is deprecated and being removed from the language, so don't reach for it in new code.
Math, loops, and logic
Sass can do arithmetic and generate repetitive CSS programmatically:
@use 'sass:math';
@for $i from 1 through 4 {
.col-#{$i} {
width: math.div($i, 4) * 100%;
}
}
That loop generates four column classes. Note the @use 'sass:math' and math.div() — Sass moved math into a proper module, and math.div() is now the correct way to divide (the old / operator for division is deprecated).
How Sass Actually Runs: The Build Step
The catch is that browsers don't understand Sass. Between writing .scss and the browser rendering it, a compiler has to run. This is the single biggest conceptual difference from writing plain CSS.
The standard flow:
- You write styles in
.scssfiles. - Dart Sass — the official, actively maintained implementation — compiles them to a
.cssfile. - You link the compiled
.cssin your HTML.
You'd typically run something like sass input.scss output.css --watch, and the --watch flag recompiles automatically every time you save. Most real projects wire this into a build tool (Vite, webpack, or a framework's tooling) so it happens invisibly on save.
A note on implementations, because you'll see old advice: Dart Sass is the only supported version today. The older Ruby Sass and the C-based LibSass are both officially deprecated and no longer get new features. If you're installing Sass in 2026, you're installing Dart Sass. Our installation guide walks through the npm and CLI setup step by step.
Sass Variables vs CSS Custom Properties
A fair question in 2026: CSS now has native variables (custom properties), so why use Sass variables? They're genuinely different tools.
Sass variables ($x) |
CSS custom properties (--x) |
|
|---|---|---|
| Resolved | At compile time | At runtime, in the browser |
| Live in the browser | No — gone after compiling | Yes — inspectable and changeable |
| Can change with JS or media queries | No | Yes |
| Cascade / inheritance | No | Yes |
| Good for | Build-time logic, math, loops | Theming, dark mode, runtime values |
The short version: Sass variables are for build-time convenience; CSS custom properties are for runtime flexibility. They coexist happily, and many modern codebases use both — Sass to generate the CSS, custom properties for the values that need to change live. Learn the native side in our CSS variables guide.
Do You Still Need Sass?
Honest answer: less often than you used to, but it's far from obsolete. Plain CSS has absorbed several of Sass's headline features. Native CSS nesting now works in every current browser, and custom properties cover a lot of what Sass variables did. If you're building something small, modern CSS may be all you need.
Where Sass still clearly pulls its weight:
- Loops and generated CSS —
@for,@each, and maps have no CSS equivalent. Generating utility classes or theme scales from a data structure is Sass territory. @useand@forward— real module system for organizing large codebases into namespaced partials.- Mixins with arguments — parameterized, reusable style blocks are still cleaner in Sass than any CSS pattern.
- Existing codebases — enormous amounts of production CSS and nearly every mature design system are written in Sass. Knowing it isn't optional if you work on real teams.
If you want the honest, feature-by-feature breakdown of what modern CSS replaced, we wrote a whole comparison on native CSS nesting vs Sass.
Getting Started in Three Steps
The fastest path from zero to compiled CSS:
- Install Dart Sass — via npm (
npm install -D sass) or a standalone install. Details in how to install Sass. - Write a
.scssfile — start by renaming an existing.cssfile; it already works as valid SCSS. - Compile with
--watch— run the CLI so every save regenerates your CSS automatically.
From there, adopt features one at a time: variables first, then nesting, then partials with @use, then mixins. You don't have to learn all of Sass at once, and you shouldn't try to.
The Bottom Line
Sass is a preprocessor that gives your stylesheets variables, nesting, reusable mixins, math, and a real module system, then compiles it all to ordinary CSS. SCSS is the CSS-like syntax you'll write in practice, and Dart Sass is the compiler you'll run. Modern CSS has closed part of the gap, but for organizing large stylesheets, generating CSS programmatically, and working in the countless codebases already built on it, Sass remains a core front-end skill. When you're ready to go deeper, the complete guide to Sass takes you from setup all the way to scalable, production-grade stylesheets.