Advanced

SASS Advanced: Logic, Functions, and Modules

Advanced SASS features unlock programmatic capabilities, allowing for complex logic, custom calculations, and a more robust, modern approach to managing dependencies.

1. Control Directives (@if, @for, @each, @while)

These allow you to introduce logic directly into your stylesheets.

  • @if/@else if/@else: Conditionally apply styles based on expressions (often involving variables).

    @mixin theme-styles($theme: light) {
      @if $theme == dark {
        background-color: #333;
        color: #eee;
      } @else {
        background-color: #fff;
        color: #333;
      }
    }
    .widget { @include theme-styles(dark); }
    
  • @for: Loop through a range of numbers to generate repetitive styles.

    // Generate grid column classes
    @for $i from 1 through 12 { // 'through' is inclusive
      .col-#{$i} { // Use interpolation #{...}
        width: percentage($i / 12);
      }
    }
    
  • @each: Iterate over items in a list or map.

    $colors: (primary: #007bff, success: #28a745, danger: #dc3545);
    
    @each $name, $color in $colors {
      .button-#{$name} {
        background-color: $color;
        &:hover {
          background-color: darken($color, 10%); // Using a built-in function
        }
      }
    }
    
  • @while: Repeat styles as long as a condition is true (less common than @for or @each).

2. Custom Functions (@function, @return)

  • Define your own reusable calculations or value manipulations.
  • Functions take arguments and must return a value using @return.

Example: Calculate REM values

$base-font-size: 16px; // Base size in pixels

@function rem($pixels) {
  @if unitless($pixels) {
    // Assume pixels if no unit provided
    @return ($pixels / $base-font-size) * 1rem;
  } @else if unit($pixels) == 'px' {
    @return ($pixels / $base-font-size) * 1rem;
  } @else {
    @error "Function rem() expects a pixel value.";
  }
}

body {
  font-size: $base-font-size; // Sets the base for rem calculations
}

h1 {
  font-size: rem(32px); // Output: 2rem
  margin-bottom: rem(20); // Output: 1.25rem (unitless input assumed px)
}

3. Modern Module System (@use, @forward)

This system is the recommended replacement for @import in modern SASS projects. It offers better control over scope and dependencies.

  • @use: Loads styles, functions, and variables from another module (file). Crucially, it namespaces the imported members by default (based on the filename). This prevents naming collisions.

    graph LR A[styles.scss] -- @use 'variables' as vars --> B[_variables.scss]; A -- @use 'components/button' --> C[_button.scss]; B -- defines $primary-color --> A; C -- defines .button-base --> A; subgraph Module Scope direction LR B --- |Namespace: variables| A; C --- |Namespace: button| A; end

    _variables.scss:

    $primary-color: #007bff;
    $base-padding: 10px;
    

    _button.scss:

    @use 'variables' as vars; // Load variables with namespace 'vars'
    
    .button {
      padding: vars.$base-padding;
      background-color: vars.$primary-color;
    }
    

    main.scss:

    @use 'variables' as v; // Use 'v' as namespace
    @use 'button'; // Use default 'button' namespace
    
    body {
      padding: v.$base-padding * 2; // Access variable via namespace
    }
    
    // Styles from button module are included automatically
    
  • @forward: Makes members (variables, mixins, functions) from another module available to files that @use the current module. It acts like a "pass-through". Often used in intermediary files (like _index.scss within a component folder) to expose specific members publicly.

    _components/_index.scss:

    @forward 'button'; // Make everything from _button.scss available
    @forward 'card' hide $internal-card-variable; // Forward card, but hide internal variable
    

    main.scss:

    @use 'components'; // Uses _components/_index.scss by default
    
    .my-button {
      @extend .button; // Can extend button class forwarded from index
    }
    

4. Built-in Modules

SASS provides powerful built-in modules (loaded via @use) for common tasks:

  • sass:math: Advanced mathematical functions (math.sqrt(), math.pow(), etc.).
  • sass:color: Manipulate colors (adjust hue, saturation, lightness, opacity, mix colors).
  • sass:string: String manipulation functions.
  • sass:list, sass:map, sass:selector: Functions for working with SASS data types and selectors.

Example using sass:color:

@use 'sass:color';

$base-color: #3498db;

.button-primary {
  background-color: $base-color;
  &:hover {
    // Make the button 10% darker on hover
    background-color: color.adjust($base-color, $lightness: -10%);
  }
  &:active {
    // Make the button 50% transparent on active
    background-color: color.adjust($base-color, $alpha: -0.5);
  }
}

By mastering these advanced features, you can write highly efficient, scalable, and maintainable CSS codebases.


Backlinks