Sass Directives

Sass: Directives

Sass 22,539 at-rules organize files, reuse styles and add compile-time logic. One small theme package shows most.

theme/_tokens.scss, theme/_index.scss and main.scssSass
// theme/_tokens.scss
$primary: #1565c0 !default;
$-secret: 1;                         // private: names starting with - or _
@mixin rounded($r: 4px) { border-radius: $r; }
// theme/_index.scss
@forward "tokens";
// main.scss
@use "sass:math";
@use "theme" as t with ($primary: #6a1b9a);
@function rem($px) {
  @if math.unit($px) != "px" { @error "rem() expects px, got #{$px}"; }
  @return math.div($px, 16px) * 1rem;
}
%btn { padding: rem(8px) rem(16px); @include t.rounded; }
@each $name, $color in (primary: t.$primary, danger: #c62828) {
  .btn-#{$name} { @extend %btn; background: $color; }
}
Compiled CSS: npx sass main.scss (blank lines removed)Sass
.btn-danger, .btn-primary {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}
.btn-primary {
  background: #6a1b9a;
}
.btn-danger {
  background: #c62828;
}
Modules: @use and @forward

@use loads a file once and namespaces its members (t. here; as * removes the prefix). Reading t.$-secret fails with Private members can't be accessed from outside their modules, and with (...) overrides !default variables. @forward re-exports members, making _index.scss a folder's public API.

The end of @import

@import shared one global scope and re-emitted CSS on every import. Dart Sass 1.80.0 (October 2024) deprecated it: each use prints DEPRECATION WARNING [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0, a release promised no sooner than two years after 1.80.0 (1.104.1 is current in September 2026). Convert with npx sass-migrator module --migrate-deps main.scss. Bootstrap 5.3 2,007 still uses @import, so Custom Builds with Sass silences its warnings.

Reuse and control flow

A mixin copies declarations into each including rule, and @content receives a block passed to @include: @mixin respond($min) { @media (width >= $min) { @content; } } wraps any rules in a breakpoint. @extend adds the selector to the extended rule; a %placeholder prints only when extended. Nested @media bubbles up, @at-root escapes nesting, and @for and @while join @each. @debug and @warn print to the terminal; @error stops the build: rem(2em) fails with Error: "rem() expects px, got 2em".