CSS vs SCSS

CSS is the styling language browsers run. SCSS (Sassy CSS) is a preprocessor flavour of Sass that adds variables, nesting, mixins, and conditionals — then compiles down to plain CSS at build time. The browser only ever runs CSS; SCSS is a developer-side convenience.

Last reviewed on 2026-04-27.

Quick Comparison

AspectCSSSCSS
Runs in the browserYesNo — compiles to CSS first
VariablesCustom properties (--name) at runtimeSass variables at compile time, plus runtime CSS custom properties
NestingNative nesting now supported in modern browsersHas had nesting since the start
Mixins / functionsNoYes — @mixin, @function, @include
Logic / loopsLimited@if, @for, @each, @while
Build stepNone requiredRequired (Dart Sass / Node Sass)
File extension.css.scss (Sassy syntax) or .sass (indented syntax)

Key Differences

1. What runs in the browser

CSS is what browsers parse and apply. Whatever you ship has to be CSS in the end.

SCSS is source. A build tool turns it into CSS, possibly minified and combined, before the browser ever sees it.

2. Variables

CSS custom properties (--brand: #2563EB) are now widely supported, evaluate at runtime, can change per element, and respond to media queries.

SCSS has its own $variables evaluated at compile. They're inlined into the output CSS — useful for static design tokens but invisible to the browser at runtime.

3. Nesting

Modern CSS supports nesting natively, with rules close to SCSS's. The need for SCSS nesting alone has shrunk.

SCSS nesting has worked everywhere for over a decade and remains common in legacy and large codebases.

4. Mixins, functions, and logic

CSS has no mixins or functions in the traditional programming sense. Custom properties and the calc(), min(), max() family give some computation, but no reusable named blocks.

SCSS's @mixin and @include let you define a styled snippet and reuse it with arguments. @function returns values. @for, @each, and @if generate CSS programmatically.

5. Build pipeline

CSS often needs no build step. Save a .css file, link it from your HTML, done.

SCSS needs a compile step. Modern toolchains (Vite, esbuild) handle it instantly; older setups (Gulp, Webpack with Sass loader) work but add complexity.

6. When SCSS still wins

For tiny sites or cases where modern CSS covers the need, plain CSS with custom properties is usually enough.

For very large codebases with shared mixins, complex generated rules (@for-driven utility classes, theming systems with many tokens), SCSS is still common and pleasant.

When to Choose Each

Choose CSS if:

  • Tiny sites where adding a build step isn't worth it.
  • Projects relying on runtime theming via custom properties and modern selectors.
  • Authoring CSS-in-JS systems where the runtime layer is JavaScript, not Sass.

Choose SCSS if:

  • Codebases with extensive shared mixins, function libraries, or complex generated styles.
  • Teams already invested in Sass tooling and conventions.
  • Theming systems that compile to many CSS bundles per brand or product.

Worked example

A small marketing landing page is fine in plain CSS — a few hundred lines, custom properties for colour tokens, no build step needed. A design-system library shipped to a dozen apps still benefits from SCSS: shared mixins for typography scales, an @each loop generating colour utility classes, conditionals in mixins that wouldn't be readable as raw CSS.

Common Mistakes

  • "SCSS is faster than CSS." Compiled SCSS becomes CSS — the runtime is identical. SCSS is a developer-experience choice, not a performance one.
  • "Modern CSS replaces SCSS." For nesting and variables, largely yes. For mixins and generated code, not yet.
  • "SCSS is dead because of CSS-in-JS." Different ecosystems. Plenty of large projects still use Sass; plenty don't.