4 Topics
Chapter•100 Minutes

Sass Variables, Values, and Interpolation

Learn Sass variables, value types, scope, assignment, null values, CSS custom properties, interpolation, and the differences between compile-time and runtime variables.

Variables and Reusable Design Tokens

Sass variables begin with $ and hold values that can be reused throughout a stylesheet. Common examples include brand colors, spacing scales, font families, border radii, breakpoints, and shadow definitions.

Sass variables are resolved during compilation. Updating $primary-color in the source changes every declaration that references it, but the resulting CSS contains ordinary values rather than the Sass variable.

Sass variables can be reassigned, although shared design tokens should generally be treated as stable values. Unnecessary reassignment makes the meaning of later declarations harder to follow.

A well-designed token system centralizes values that must remain consistent while allowing component-specific values where genuine variation is needed.

Create a Design Token Set
$color-primary: #5b5bd6;
$color-text: #222;
$space-sm: 0.5rem;
$space-md: 1rem;
$radius-md: 0.5rem;

.button {
  padding: $space-sm $space-md;
  color: white;
  background: $color-primary;
  border: 0;
  border-radius: $radius-md;
}

body {
  color: $color-text;
}
💡 Each variable represents a reusable design decision. If the primary brand color changes, components that reference $color-primary receive the updated compiled value. Use descriptive token names so that the intention of a value is clear. Semantic names such as $color-primary are often more maintainable than names based only on appearance, such as $purple.
Key Takeaways
  • Sass variables begin with $.
  • Variables are useful for repeated design decisions.
  • Semantic tokens communicate intent more clearly than arbitrary names.
  • Sass variables are resolved at compile time.
Knowledge Check

What happens when a Sass variable is changed and the stylesheet is recompiled?

Sass Data Types and Value Operations

Sass supports several value types:

  • Numbers: Integers, decimals, and values with units such as 16px, 1rem, and 90deg.
  • Strings: Quoted or unquoted text values.
  • Colors: Named colors, hexadecimal values, and supported color functions.
  • Booleans: true and false.
  • Null: Represents the absence of a value.
  • Lists: Ordered collections of values.
  • Maps: Key-value collections.
  • Functions and calculation expressions: Values and computations used to derive stylesheet output.

Sass arithmetic and unit handling can be helpful for deriving values, but units must be compatible. Adding 1rem and 2rem is meaningful; adding 1rem and 2seconds is not.

Modern CSS also supports its own runtime calculations through calc(), min(), max(), and clamp(). Use Sass arithmetic for compile-time calculations and CSS calculations when the browser needs to combine runtime values such as viewport dimensions and custom properties.

Working with Values and Units
$base-size: 1rem;
$scale: 1.25;
$heading-size: $base-size * $scale;
$spacing: 8px;
$double-spacing: $spacing * 2;
$optional-border: null;

.card {
  font-size: $heading-size;
  padding: $double-spacing;
  border: $optional-border;
}
💡 Sass calculates $heading-size and $double-spacing during compilation. The null value does not produce a useful CSS border declaration, so Sass omits that declaration. Arithmetic involving CSS units and numeric values follows Sass's calculation rules. When combining units, ensure the operation is dimensionally meaningful and supported by the compiler.
Knowledge Check

Which Sass value represents the absence of a value and can cause a declaration to be omitted?

Variable Scope, Defaults, and Configuration

Variable scope determines where a variable can be accessed. Variables declared at the top level are available throughout their relevant module scope, while variables declared inside blocks or functions may have more limited visibility.

Sass supports default assignments with !default. This flag assigns a value only when the variable is not already defined or is defined as null. It is useful for configurable libraries and themes.

The !global flag can update an existing global variable from a nested scope. Although valid in supported situations, global reassignment makes dependencies less explicit and should be avoided in ordinary component styling.

In the module system, configuration is commonly applied through @use with a with clause. The configured variables must be exposed appropriately by the module, generally using !default on the variables intended for configuration.

Avoid hidden global dependencies

Prefer explicit module configuration and parameters over repeated global variable reassignment. Explicit dependencies are easier to test and maintain.

Configurable Theme Tokens
$brand-color: #cc6699 !default;
$border-radius: 0.5rem !default;

.button {
  background-color: $brand-color;
  border-radius: $border-radius;
}
💡 The !default flag allows a variable to receive a value supplied by an appropriate configuration context when the module is loaded. It is especially useful for Sass libraries that expose customizable design tokens. For a module called theme, configuration can be supplied with @use "theme" with ($brand-color: #336699); when the module's configurable variables meet Sass's module configuration requirements.
Knowledge Check

What is the main purpose of the `!default` flag on a Sass variable?

Sass Variables Versus CSS Custom Properties

Sass variables and CSS custom properties solve related but different problems.

A Sass variable such as $primary-color is resolved during compilation. A CSS custom property such as --primary-color is available in the browser's CSS cascade and can change dynamically based on inheritance, selectors, themes, and JavaScript.

Use Sass variables for compile-time constants and code-generation logic. Use CSS custom properties when a value needs to vary at runtime, respond to a theme class, inherit through the DOM, or be changed by JavaScript.

The two systems work well together. Sass can organize the token definitions while emitting CSS custom properties for runtime use.

Sass variables
Resolution: Compile time
The compiler substitutes values into generated CSS.
Scope: Sass module and lexical scopes
Access depends on Sass scope and module visibility.
CSS custom properties
Resolution: Browser runtime
Values participate in the CSS cascade.
Dynamic changes: Supported
Values can change through CSS rules or JavaScript.
Compile-Time and Runtime Tokens
$default-brand: #5b5bd6;

:root {
  --brand-color: #{$default-brand};
  --surface-color: #ffffff;
}

[data-theme="dark"] {
  --surface-color: #171717;
}

.button {
  background: var(--brand-color, #5b5bd6);
  color: white;
}

.page {
  background: var(--surface-color);
}
💡 Sass interpolates $default-brand into the CSS custom-property declaration. The resulting --brand-color and --surface-color values remain runtime CSS custom properties. A theme selector can change --surface-color without recompiling Sass. The browser resolves var() according to the CSS cascade and inheritance rules.
Knowledge Check

Which variable type is most suitable for switching a component theme dynamically in the browser?