Sass @debug Rule

Beginner
9 min read
Updated: Nov 2026
5 examples
Compiled CSS

Definition and Usage

The Sass @debug rule is written @debug <expression>;. It prints the value of that expression along with the filename and line number so you can inspect variables and calculations while developing.

Compilation continues and CSS still ships — debug lines go to the terminal / build log, not into the CSS file. Pass any Sass value, not just strings; Sass prints the same representation as meta.inspect().

Official pattern.

Per the Sass docs: log intermediate mixin math (for example a divider offset) with a labeled string before the value becomes CSS.

Development aid.

Use @debug for yourself while building. Prefer @warn / @error when messaging library users.

Remove before shipping.

Leave debug statements out of production builds so logs stay clean. Comment them out or delete them when finished.

Syntax

SCSS
@mixin inset-divider-offset($offset, $padding) {
  $divider-offset: (2 * $padding) + $offset;
  @debug "divider offset: #{$divider-offset}";

  margin-left: $divider-offset;
  width: calc(100% - #{$divider-offset});
}

Dart Sass prints something like test.scss:3 Debug: divider offset: 132px. Exact formatting varies by implementation.

@debug vs @warn vs @error

Pick the right messaging at-rule:

At-ruleStops compile?Best for
@debugNoInspecting values while developing
@warnNoDeprecations and soft tips for API users
@errorYesInvalid usage that must not continue

SCSS Examples

Each example still produces CSS. Open View Compiled CSS and View Debug Output to see both sides.

Example 1 — Debug a Computed Length

Official-style mixin: inspect an offset before it becomes CSS.

SCSS
@mixin inset-divider-offset($offset, $padding) {
  $divider-offset: (2 * $padding) + $offset;
  @debug "divider offset: #{$divider-offset}";

  margin-left: $divider-offset;
  width: calc(100% - #{$divider-offset});
}

.panel {
  @include inset-divider-offset(12px, 60px);
}

How It Works

  1. Compute (2 * 60px) + 12px → 132px.
  2. Log the labeled value with @debug.
  3. Emit CSS that uses the same offset.
  4. Confirm the math in the log without guessing from CSS alone.

Example 2 — Maps, Lists & Types

Pass non-string values directly to @debug.

SCSS
@use "sass:map";
@use "sass:list";
@use "sass:meta";

$theme: (
  primary: #036,
  radius: 8px,
);

@debug $theme;
@debug map.get($theme, primary);
@debug list.nth(10px 20px 30px, 2);
@debug meta.type-of(#036);

.box {
  color: map.get($theme, primary);
  border-radius: map.get($theme, radius);
  padding: list.nth(10px 20px 30px, 2);
}

How It Works

  1. Maps print in parentheses like meta.inspect.
  2. Colors and lengths print as Sass values.
  3. meta.type-of reports color for #036.
  4. CSS still uses the same map / list lookups.

Example 3 — Debug Inside a Function

Log each call’s inputs and result from a rem() helper.

SCSS
@use "sass:math";

@function rem($px, $base: 16px) {
  $result: math.div($px, $base) * 1rem;
  @debug "rem(#{$px}, #{$base}) => #{$result}";
  @return $result;
}

.title {
  font-size: rem(24px);
  padding: rem(8px, 16px);
}

How It Works

  1. Each call prints once with inputs and result.
  2. Useful when a helper is used in many places.
  3. @return still runs — debug does not change the value.
  4. Remove the log after the conversions look right.

Example 4 — Debug Inside a Loop

Print every breakpoint name and width while generating media queries.

SCSS
$breakpoints: (
  sm: 480px,
  md: 768px,
  lg: 1024px,
);

@each $name, $width in $breakpoints {
  @debug "breakpoint #{$name} = #{$width}";

  @media (min-width: $width) {
    .container-#{$name} {
      max-width: $width;
    }
  }
}

How It Works

  1. One debug line per map entry.
  2. Then the matching @media rule is emitted.
  3. Confirms keys and widths before you hunt CSS.
  4. Pairs well with @each when generating utilities.

Example 5 — Colors, Maps, Null & Strings

See how different Sass types look in the debug log.

SCSS
@use "sass:color";
@use "sass:meta";

$brand: #036;

@debug $brand;
@debug color.scale($brand, $lightness: 40%);
@debug meta.inspect((ok: true, count: 3));
@debug null;
@debug "plain string";

.swatch {
  background: $brand;
  color: color.scale($brand, $lightness: 40%);
}

How It Works

  1. Any value works — colors, maps, null, strings.
  2. Same idea as meta.inspect() for representation.
  3. Scaled color prints before it lands in CSS.
  4. Great for spotting unexpected null or type mixes.

Edge Cases & Pitfalls

Most @debug issues are noisy logs, wrong at-rule choice, or looking for messages in CSS.

css

Nothing appears in the CSS file

Debug lines go to the compiler log. If the stylesheet compiles, look in the terminal — not DevTools CSS.

noise

Loops can spam the log

Debugging every @each / @for iteration fills the console. Narrow the condition or remove after checking.

api

Not for library users

Use @warn for soft tips and @error for hard fails. @debug is a developer flashlight.

ship

Strip before production

Forgotten @debug statements clutter CI logs and can leak internal token shapes.

Sass Support

@debug is a core Dart Sass at-rule. Message formatting differs slightly by implementation; behavior (print and continue) is the same.

ImplementationStatus
Dart SassSupported (recommended)
LibSass / node-sassSupported (deprecated toolchain)
Ruby SassSupported (end-of-life)
BrowsersN/A — messages never reach CSS

Prefer Dart Sass for new projects. SCSS and indented syntax both support @debug.

Key Takeaways

  • Inspect: @debug <expr>; prints value + file + line.
  • Any value works — same representation as meta.inspect().
  • Does not stop the build; CSS still ships.
  • Temporary: remove before production; use @warn / @error for APIs.

One line: @debug is a compile-time flashlight — print values, keep building.

Compile Notes

@debug never reaches the browser. Conceptual flow:

flow.txt
1. Evaluate the @debug expression
2. Print filename, line, and inspected value to the log
3. Continue compiling (do not stop)
4. Emit CSS as usual — debug text stays out of the stylesheet

Frequently Asked Questions

It prints the value of an expression along with the filename and line number so you can inspect variables and calculations while developing your stylesheet.
No. Like @warn, it continues compiling and still emits CSS. Only @error stops the build.
Yes. You can pass any value. Sass prints the same representation as meta.inspect().
In the compiler / terminal / build log—not in the CSS file. Exact formatting varies by Sass implementation.
@debug is for inspecting values during development. @warn is for soft guidance to API users (deprecations, tips) and usually includes a stack trace meant for callers.
No. Remove or comment out debug statements before shipping so build logs stay clean. Prefer temporary checks while developing.

Next: Sass @at-root Rule

Escape nesting and emit selectors at the document root.

Sass @at-root Rule →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful