Skip to content

Sass and CSS Output — Complete Guide

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about Sass and CSS Output. We cover key concepts, practical examples, and best practices to help you master this topic.

Control how Sass compiles to CSS with output styles (expanded, compressed), source maps, debug output, and @debug, @warn, and @error directives for development feedback.

What You'll Learn

  • Output styles: expanded, compressed
  • Source maps for debugging
  • The @debug, @warn, and @error directives
  • Silent comments vs output comments
  • Controlling selector output
  • CSS output optimization

Why It Matters

  • Development output must be readable
  • Production output must be minimized
  • Source maps enable SCSS debugging in DevTools
  • Warnings help catch issues during development

Real-World Use

  • A CI pipeline compresses CSS for production
  • A developer uses expanded output with source maps for debugging
  • A library uses @warn to deprecate old APIs
  • A build script validates variables with @error
flowchart LR
  A[Sass Compilation] --> B[Output Style]
  A --> C[Source Maps]
  A --> D[Debug Directives]
  B --> E[expanded: readable]
  B --> F[compressed: minified]
  C --> G[DevTools mapping]
  D --> H[@debug, @warn, @error]

Output Control

Code Example: Output Styles

# Expanded output (development)
sass src/main.scss dist/main.css --style expanded

# Compressed output (production)
sass src/main.scss dist/main.min.css --style compressed

# Nested output (default)
sass src/main.scss dist/main.css --style nested  # Default

# Compact output (less common)
sass src/main.scss dist/main.css --style compact
// Input SCSS
$primary: #0066CC;

.card {
    background: #fff;
    border: 1px solid #eee;

    &__title {
        font-size: 1.25rem;
        color: $primary;
    }

    &__text {
        color: #666;
    }
}

// Expanded output
.card {
    background: #fff;
    border: 1px solid #eee;
}

.card__title {
    font-size: 1.25rem;
    color: #0066CC;
}

.card__text {
    color: #666;
}

// Compressed output
.card{background:#fff;border:1px solid #eee}.card__title{font-size:1.25rem;color:#0066CC}.card__text{color:#666}

Expected output: Expanded output preserves readability with proper indentation. Compressed output removes all whitespace and newlines. Nested output shows nesting hierarchy with indentation.

Code Example: Source Maps

# Generate source maps
sass src/main.scss dist/main.css --source-map

# Source map URL embedded (default)
sass src/main.scss dist/main.css --source-map --embed-sources

# No source map (production)
sass src/main.scss dist/main.css --no-source-map
// Input: _card.scss (line 12)
.card {
    background: #fff;   // line 13
    padding: 1rem;      // line 14
}
/* Output with source map */
.card { background: #fff; padding: 1rem; }
/*# sourceMappingURL=main.css.map */
// main.css.map (truncated)
{
    "version": 3,
    "sources": ["_card.scss"],
    "names": [],
    "mappings": "AAKA,MAAM,IAAI,UAAU,EAAE,OAAO,EAAE,IAAI,KAAK",
    "file": "main.css"
}

Expected output: Source maps link compiled CSS back to the original SCSS lines. In DevTools, styles show the .scss file and line number instead of the .css file. This makes debugging SCSS possible.

Code Example: @debug, @warn, @error

@use 'sass:meta';

// @debug - print during compilation (continues)
$theme: 'dark';
@debug "Building theme: #{$theme}";
// Console: src/main.scss:3 Debug: Building theme: dark

// @warn - warning message (continues)
@mixin deprecated-mixin {
    @warn "This mixin is deprecated. Use new-mixin() instead.";
    // Implementation...
}

$primary: #0066CC;
@if meta.variable-exists('old-primary') {
    @warn "Variable $old-primary is deprecated. Use $primary instead.";
}

// @error - stop compilation with message
@function bp($name) {
    $breakpoints: (
        'sm': 480px,
        'md': 768px,
        'lg': 1024px
    );

    @if not map.has-key($breakpoints, $name) {
        @error "Unknown breakpoint '#{$name}'. Valid breakpoints are: #{map.keys($breakpoints)}";
    }

    @return map.get($breakpoints, $name);
}

// This works:
.container { max-width: bp('md'); }

// This would fail compilation:
// .container { max-width: bp('xl'); }
// Error: Unknown breakpoint 'xl'. Valid breakpoints are: sm, md, lg

// Validation pattern
@mixin validate-color($color) {
    @if type-of($color) != 'color' {
        @error "Invalid color: #{$color}. Provide a valid Sass color value.";
    }

    @if color.lightness($color) < 15% {
        @warn "Color #{$color} is very dark. Text on this background may be hard to read.";
    }
}

$header-bg: #1a1a2e;
@include validate-color($header-bg);  // Warning: very dark color

Expected output: @debug prints values for development inspection. @warn shows deprecation or caution messages but continues compilation. @error stops compilation with a clear error message, preventing invalid CSS from being generated.

Code Example: Comments and Output

// This is a silent comment - never appears in CSS output

/* This is a regular CSS comment - appears in expanded output */

/*! This is a preserved comment - appears even in compressed output */

// Silent comments are great for internal notes
$primary: #0066CC;  // This inline note is also silent

/*!
 * License: MIT
 * Author: Your Name
 * This copyright notice survives compression
 */

.card {
    /* This comment appears in expanded output */
    background: #fff;

    // This silent comment does not appear in CSS
    padding: 1rem;

    /*! Preserved even in compressed */
    border: 1px solid #eee;
}

// Compressed output:
// .card{background:#fff;border:1px solid #eee}
// /*! comments survive */
# Control comment output
# --no-source-map to remove source maps
# Comments with /*! */ are always preserved

Expected output: // (silent) comments never appear in CSS. /* / comments appear in expanded but not compressed output. /! / comments appear in all output styles including compressed. Use /! */ for licenses and copyright.

Common Mistakes

  1. Using expanded output in production — Expanded output is 3-5x larger than compressed. Always use compressed for production.
  2. Forgetting source maps in development — Without source maps, DevTools shows compiled CSS, making debugging much harder.
  3. Not handling @error gracefully — @error stops compilation. Ensure validation runs before expensive computations.
  4. Leaving @debug in production code — Remove or comment out @debug statements before production builds.
  5. Confusing /* / and // — // comments are silent. Use / / or /! */ for documentation that should appear in CSS.
  6. Not using --no-source-map in production — Source maps in production expose source file structure. Omit them.
  7. Relying on nested output style — Nested output is rarely used. Use expanded for dev and compressed for prod.

Practice Questions

  1. What is the default Sass output style? Nested (--style nested).
  2. What is the difference between @debug and @warn? @debug prints a message without warning. @warn prints a warning that users can configure to be treated as errors.
  3. How do you prevent /* */ comments from appearing in compressed CSS? Use // (silent comments) which never appear in any CSS output.
  4. What file extension does a source map use? .css.map (e.g., main.css.map).

FAQ

Should I commit source maps to version control?

No. Add *.css.map to .gitignore. Generate source maps only during local development.

Can I customize the source map output?

Yes. Use --source-map-urls (relative or absolute), --embed-sources (embed SCSS content), and --embed-source-map (embed map in CSS).

How do I make @warn fail the build?

Use the --fatal-warnings flag. Any @warn or deprecation warning becomes a compilation error.

Mini Project

Set up a complete Sass build pipeline for both development and production. Configure: (1) dev build with expanded output, source maps, and @debug/@warn messages visible, (2) production build with compressed output, no source maps, and @error for invalid values, (3) validate all color variables with a mixin that uses @error for invalid types and @warn for low-contrast colors, (4) use /*! */ comments for a license header that survives compression, (5) test that @error stops compilation with a helpful message, (6) verify the compressed output removes all whitespace, and (7) confirm source maps work in Chrome DevTools.

What's Next

Continue with Lesson 15: Sass Architecture to learn project structure patterns for Sass.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro