Skip to content

Sass Variables — Complete Guide

DodaTech Updated 2026-06-28 5 min read

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

Sass variables store reusable values like colors, fonts, and spacing using dollar sign syntax with scope rules, default flags, and support for multiple data types.

What You'll Learn

  • Declaring and using Sass variables
  • Variable scope and hoisting
  • The !default flag for configurable variables
  • Data types: colors, numbers, strings, lists, maps
  • Variable naming conventions
  • Sass variables vs CSS custom properties
  • Interpolation with #{} syntax

Why It Matters

  • Hard-coded values are difficult to maintain
  • Variables create a single source of truth
  • Theming becomes straightforward
  • Variables improve code readability

Real-World Use

  • A design system defines all colors as variables
  • A themed site swaps variable values for light/dark mode
  • A spacing scale uses variables for consistent rhythm
  • A component library exposes variables for customization
flowchart LR
  A[Sass Variables] --> B[Color]
  A --> C[Font]
  A --> D[Spacing]
  A --> E[Breakpoints]
  A --> F[Config]
  B --> G[$primary, $secondary]
  C --> H[$font-body, $font-heading]
  D --> I[$spacing-unit, $gap]

Working with Variables

Code Example: Variable Declaration and Usage

// Colors
$primary: #0066CC;
$secondary: #6c757d;
$success: #28a745;
$danger: #dc3545;
$warning: #ffc107;
$info: #17a2b8;
$light: #f8f9fa;
$dark: #343a40;

// Typography
$font-family-sans: 'Inter', system-ui, -apple-system, sans-serif;
$font-family-mono: 'Fira Code', 'Cascadia Code', monospace;
$font-size-base: 16px;
$font-size-lg: 1.25rem;
$font-size-sm: 0.875rem;
$line-height-base: 1.6;
$font-weight-normal: 400;
$font-weight-bold: 700;

// Spacing
$spacing-unit: 8px;
$spacing-xs: $spacing-unit * 0.5;   // 4px
$spacing-sm: $spacing-unit;         // 8px
$spacing-md: $spacing-unit * 2;     // 16px
$spacing-lg: $spacing-unit * 3;     // 24px
$spacing-xl: $spacing-unit * 4;     // 32px
$spacing-xxl: $spacing-unit * 6;    // 48px

// Usage
body {
    font-family: $font-family-sans;
    font-size: $font-size-base;
    line-height: $line-height-base;
    color: $dark;
}

.btn-primary {
    background: $primary;
    color: #fff;
    padding: $spacing-sm $spacing-md;
    border-radius: 4px;
}

.alert-success {
    background: $success;
    color: #fff;
    padding: $spacing-md;
}

Expected output: Variables make the CSS consistent and easy to update. Changing $primary to a different color updates all instances across the stylesheet.

Code Example: Scope and !default

// Global scope
$primary: #0066CC;
$border-radius: 4px;

// Scope in a block
.card {
    $card-padding: 16px;  // Block scope
    padding: $card-padding;
    border-radius: $border-radius;
    background: $primary;
}

// .footer can't access $card-padding
// .footer { padding: $card-padding; } // Error: undefined variable

// !default flag - sets value only if not already defined
// _variables.scss
$primary: #0066CC !default;
$font-size-base: 16px !default;

// _theme.scss (loaded after _variables.scss)
$primary: #ff6600;  // Overrides !default value
$font-size-base: 18px;  // Overrides !default value

Expected output: Variables with !default can be overridden by assigning a new value before the default is loaded. This enables configurable theme files that override defaults.

Code Example: Data Types

// Numbers (with units)
$width: 100px;
$duration: 0.3s;
$line-height: 1.5;
$rotation: 45deg;

// Strings
$font-stack: 'Helvetica', Arial, sans-serif;
$direction: left;

// Colors
$hex: #ff6600;
$rgb: rgb(255, 102, 0);
$rgba: rgba(255, 102, 0, 0.5);
$hsl: hsl(24, 100%, 50%);

// Lists (arrays)
$sizes: 10px, 20px, 30px, 40px;
$fonts: 'Inter', 'Helvetica', Arial, sans-serif;
$breakpoints: 480px, 768px, 1024px, 1280px;

// Maps (objects)
$theme-colors: (
    'primary': #0066CC,
    'secondary': #6c757d,
    'success': #28a745,
    'danger': #dc3545
);

$breakpoint-map: (
    'sm': 480px,
    'md': 768px,
    'lg': 1024px,
    'xl': 1280px
);

// Boolean
$is-dark-mode: false;
$enable-shadows: true;

// Null
$custom-color: null;  // Not set

// Interpolation in selectors and property names
$component: 'alert';
$property: 'margin';

.#{$component}-danger {
    background: map-get($theme-colors, 'danger');
    #{$property}-top: 1rem;
}

Expected output: Sass supports all common programming data types. Lists and maps enable powerful iteration patterns. Interpolation (#{}) inserts variable values into selectors and property names.

Code Example: Sass Variables vs CSS Custom Properties

// Sass variables: compiled to fixed values
$primary: #0066CC;
.button { background: $primary; }
// Compiled: .button { background: #0066CC; }

// CSS custom properties: dynamic, can change at runtime
:root {
    --primary: #0066CC;
}
.button { background: var(--primary); }
// Stays as var(--primary) in compiled CSS

// Combined approach
:root {
    --primary: #{$primary};  // Sass variable sets default
    --spacing: #{$spacing-md};
}

.button {
    background: var(--primary);
    padding: var(--spacing);
}

// Override at runtime with a class
.dark-mode {
    --primary: #ff6600;
    --spacing: 24px;
}

Expected output: Sass variables are replaced with their values at compile time. CSS custom properties stay dynamic and can be changed at runtime (media queries, JavaScript, dark mode).

Common Mistakes

  1. Assuming Sass variables are dynamic — Sass variables are compile-time only. Use CSS custom properties for runtime changes.
  2. Not using !default for library variables — Library authors should use !default so consumers can override values.
  3. Over-naming with redundant prefixes — $color-primary instead of $primary. Keep names concise but clear.
  4. Mutating variables unnecessarily — Create new variables instead of reassigning. Reassignment can cause confusing side effects with scope.
  5. Using generic names like $color or $size — Be specific: $brand-primary, $spacing-md, $font-size-body.
  6. Not using interpolation for dynamic selectors — Variables in selectors need #{} syntax: .#{$class-name} { }
  7. Using too many variables — Only create variables for values used more than once or values that need central control.

Practice Questions

  1. What syntax declares a Sass variable? The dollar sign: $variable-name: value;
  2. What does the !default flag do? Sets a default value for a variable that can be overridden if the variable is already defined.
  3. What is the difference between Sass lists and maps? Lists are ordered collections accessed by index. Maps are key-value pairs accessed by key.
  4. When should you use CSS custom properties instead of Sass variables? When values need to change at runtime (dark mode, theme switching, dynamic updates).

FAQ

Can I use Sass variables in media queries?

Sass 3.4+ allows variables in media queries. Earlier versions required interpolation. Example: @media (min-width: $breakpoint-md).

Should I use hyphens or camelCase for variable names?

Hyphens are conventional in Sass ($primary-color). Be consistent with your team and existing codebase.

How do I organize variables?

Create a _variables.scss partial imported first. Group by category: colors, typography, spacing, breakpoints, z-index.

Mini Project

Create a _variables.scss file with a complete design token system: 10 color variables (primary, secondary, success, danger, warning, info, light, dark, body-bg, body-color), a typography scale (5 font sizes with corresponding line heights), a spacing scale (xs through xxl based on an 8px unit), 4 breakpoint variables, and 3 z-index variables. Build a sample component library (buttons, cards, alerts, badges) that uses only these variables. Demonstrate how changing one variable ($primary) updates all components.

What's Next

Continue with Lesson 4: Sass Nesting to learn how nesting improves CSS organization.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro