SASS/SCSS

Lists & Interpolation

20 min Lesson 17 of 30

Introduction to SASS Lists

SASS lists are ordered collections of values separated by spaces or commas. They are similar to arrays in other programming languages but have a unique syntax in SASS. Lists are fundamental data structures that enable you to store multiple related values in a single variable and perform operations on them.

What Are SASS Lists?

A list can contain any type of value: numbers, strings, colors, booleans, null, or even other lists. Lists in SASS are 1-indexed (the first item is at position 1, not 0):

List Examples

// Space-separated list
$fonts: Arial Helvetica sans-serif;

// Comma-separated list
$sizes: 12px, 16px, 20px, 24px;

// Mixed values
$mixed: 10px solid #333;

// Single value (still a list)
$single: 1rem;

// Empty list
$empty: ();

// List of lists
$matrix: (1 2 3), (4 5 6), (7 8 9);
Note: Space-separated lists are used when values naturally belong together (like font stacks or border properties). Comma-separated lists are used when values are distinct items in a collection (like multiple sizes or colors).

When to Use Lists vs Maps

Choose lists when you need:

  • An ordered collection of values
  • To iterate through values in sequence
  • Simple arrays without key-value associations
  • CSS property values (border, font-family, box-shadow)

Choose maps when you need:

  • Key-value pairs for named access
  • Configuration objects
  • Data that needs descriptive keys
  • Nested data structures

Creating and Accessing Lists

List Indexing with nth()

Access list items by position using the nth() function. Remember: SASS lists are 1-indexed!

Accessing List Items

$colors: red, green, blue, yellow;

.first {
  color: nth($colors, 1); // red
}

.second {
  color: nth($colors, 2); // green
}

.last {
  color: nth($colors, -1); // yellow (negative indexes count from end)
}

// Using in calculations
$sizes: 10px, 20px, 30px;
$base-size: nth($sizes, 1); // 10px
$double-size: nth($sizes, 2) * 2; // 40px
Warning: Accessing an index that doesn't exist will cause a SASS compilation error. Always check list length or use conditional logic when accessing dynamic positions.

Getting List Length

Use length() to get the number of items in a list:

List Length

$breakpoints: 576px, 768px, 992px, 1200px;
$count: length($breakpoints); // 4

// Safe access pattern
@function safe-nth($list, $index, $fallback: null) {
  @if $index > 0 and $index <= length($list) {
    @return nth($list, $index);
  }
  @return $fallback;
}

$color: safe-nth($colors, 10, #000); // Returns #000 if index invalid

Modifying Lists

Adding Items with append()

Add items to the end of a list using append():

Appending to Lists

$colors: red, green;
$colors: append($colors, blue); // red, green, blue
$colors: append($colors, yellow, comma); // red, green, blue, yellow

// Specify separator explicitly
$spaced-list: append((), first, space); // first
$spaced-list: append($spaced-list, second, space); // first second

// Building lists dynamically
$sizes: ();
@for $i from 1 through 5 {
  $sizes: append($sizes, $i * 10px);
}
// Result: 10px, 20px, 30px, 40px, 50px
Note: Like maps, lists in SASS are immutable. append() returns a new list; it doesn't modify the original. You must reassign the result to update your variable.

Joining Lists with join()

Combine two lists into one using join():

Joining Lists

$list1: red, green;
$list2: blue, yellow;

$combined: join($list1, $list2); // red, green, blue, yellow
$combined-comma: join($list1, $list2, comma); // Force comma separator
$combined-space: join($list1, $list2, space); // Force space separator

// Practical example: combining breakpoint values
$mobile-bp: 320px, 480px;
$tablet-bp: 768px, 1024px;
$all-bp: join($mobile-bp, $tablet-bp); // 320px, 480px, 768px, 1024px

Finding Items with index()

Find the position of a value in a list using index():

Finding List Items

$colors: red, green, blue, yellow;

$position: index($colors, blue); // 3
$not-found: index($colors, purple); // null

// Conditional check
@if index($colors, red) {
  .has-red {
    color: red;
  }
}

// Create a contains function
@function list-contains($list, $value) {
  @return index($list, $value) != null;
}

@if list-contains($colors, green) {
  .success { color: green; }
}

Iterating Over Lists

Using @each with Lists

Loop through list items to generate CSS dynamically:

Basic List Iteration

$sizes: small, medium, large;

@each $size in $sizes {
  .btn-#{$size} {
    padding: 0.5rem 1rem;
    font-size: 1rem;

    @if $size == small {
      padding: 0.25rem 0.5rem;
      font-size: 0.875rem;
    } @else if $size == large {
      padding: 0.75rem 1.5rem;
      font-size: 1.125rem;
    }
  }
}

Iterating with Index

Sometimes you need both the value and its position:

Iteration with Index

$colors: red, green, blue;

@each $color in $colors {
  $i: index($colors, $color);

  .color-#{$i} {
    background: $color;
    z-index: $i;
  }
}

// Generated CSS:
// .color-1 { background: red; z-index: 1; }
// .color-2 { background: green; z-index: 2; }
// .color-3 { background: blue; z-index: 3; }

Advanced Iteration Patterns

Multiple Lists in Parallel

$names: primary, secondary, accent;
$colors: #3498db, #2ecc71, #9b59b6;

@each $name in $names {
  $i: index($names, $name);
  $color: nth($colors, $i);

  .bg-#{$name} {
    background-color: $color;
  }

  .text-#{$name} {
    color: $color;
  }
}

String Interpolation

What Is Interpolation?

Interpolation allows you to insert variable values into strings using the #{$variable} syntax. This is essential when you need to dynamically generate selectors, property names, or parts of property values.

Basic Interpolation

$side: left;
$size: 20;

.element {
  margin-#{$side}: #{$size}px; // margin-left: 20px
  border-#{$side}-color: red;  // border-left-color: red
}

// Without interpolation (ERROR)
// .element {
//   margin-$side: $size px; // This won't work!
// }
Tip: Interpolation is required when inserting variables into property names, selectors, or when you need to convert a variable to a string. For simple property values, you can usually use variables directly without interpolation.

Interpolation in Selectors

Generate class names, IDs, and attribute selectors dynamically:

Dynamic Selectors

$theme: dark;

.theme-#{$theme} {
  background: #333;
  color: #fff;
}
// Result: .theme-dark { ... }

// Generate multiple selectors
$states: hover, focus, active;

@each $state in $states {
  .button:#{$state} {
    outline: 2px solid blue;
  }
}
// Result: .button:hover, .button:focus, .button:active

// Attribute selectors
$data-attr: status;
$value: active;

[data-#{$data-attr}="#{$value}"] {
  color: green;
}
// Result: [data-status="active"] { color: green; }

Interpolation in Property Names

Create dynamic property names based on variables:

Dynamic Property Names

$sides: top, right, bottom, left;

@each $side in $sides {
  .no-margin-#{$side} {
    margin-#{$side}: 0;
  }

  .border-#{$side} {
    border-#{$side}: 1px solid #ddd;
  }
}

// Directional mixin
@mixin spacing($property, $direction, $value) {
  #{$property}-#{$direction}: $value;
}

.element {
  @include spacing(margin, top, 20px);    // margin-top: 20px
  @include spacing(padding, left, 10px);  // padding-left: 10px
}

Interpolation in Property Values

While usually not necessary for simple values, interpolation is useful for concatenating strings:

Value Interpolation

$image-path: "/images/";
$filename: "hero.jpg";

.hero {
  background-image: url("#{$image-path}#{$filename}");
  // Result: url("/images/hero.jpg")
}

// Content strings
$heading: "Welcome";

.banner::before {
  content: "#{$heading} to our site";
  // Result: content: "Welcome to our site"
}

// Combining units
$size: 16;
$unit: px;

.text {
  font-size: #{$size}#{$unit}; // 16px
}
Note: For simple property values like colors, sizes, or numbers, you don't need interpolation. Use color: $primary-color not color: #{$primary-color}. Interpolation is primarily for selectors, property names, and string concatenation.

Interpolation in @media Queries

Build dynamic media queries with interpolation:

Dynamic Media Queries

$breakpoint: 768px;
$query-type: min-width;

@media (#{$query-type}: $breakpoint) {
  .container {
    max-width: 720px;
  }
}
// Result: @media (min-width: 768px) { ... }

// Flexible media query mixin
@mixin respond($condition, $value) {
  @media (#{$condition}: $value) {
    @content;
  }
}

.element {
  width: 100%;

  @include respond(min-width, 768px) {
    width: 750px;
  }

  @include respond(max-height, 600px) {
    height: auto;
  }
}

Interpolation in Comments

Include variable values in comments for documentation:

Documented Variables

$version: "2.1.0";
$author: "Development Team";

/*
 * Theme Version: #{$version}
 * Author: #{$author}
 * Generated: #{inspect(selector-parse(".test"))}
 */

// In compiled CSS:
/*
 * Theme Version: 2.1.0
 * Author: Development Team
 * Generated: .test
 */

When to Use Interpolation vs Direct Variables

Interpolation Guidelines

// ✓ CORRECT: Direct variable in value
.element {
  color: $primary-color;
  width: $container-width;
  margin: $spacing-md;
}

// ✗ INCORRECT: Unnecessary interpolation
.element {
  color: #{$primary-color};
  width: #{$container-width};
}

// ✓ CORRECT: Interpolation in selector
.theme-#{$theme-name} {
  background: $bg-color;
}

// ✓ CORRECT: Interpolation in property name
.element {
  margin-#{$side}: 20px;
}

// ✓ CORRECT: Interpolation for string concatenation
.element {
  background-image: url("#{$path}/#{$filename}");
}

// ✓ CORRECT: Interpolation in media queries
@media (min-width: #{$breakpoint}) {
  ...
}

Practical Examples

Example 1: Grid System Generator

Dynamic Grid Classes

$columns: 1, 2, 3, 4, 6, 12;

@each $col in $columns {
  .col-#{$col} {
    width: percentage(1 / $col);
    flex: 0 0 percentage(1 / $col);
  }
}

// Generate offset classes
@each $col in $columns {
  @if $col < 12 {
    .offset-#{$col} {
      margin-left: percentage($col / 12);
    }
  }
}

Example 2: Icon Sizes

Icon Size Utilities

$icon-sizes: (
  xs: 12px,
  sm: 16px,
  md: 24px,
  lg: 32px,
  xl: 48px
);

@each $name, $size in $icon-sizes {
  .icon-#{$name} {
    width: $size;
    height: $size;
    font-size: $size;
  }
}

Example 3: State Utilities

State-based Classes

$states: success, warning, error, info;
$state-colors: #2ecc71, #f39c12, #e74c3c, #3498db;

@each $state in $states {
  $i: index($states, $state);
  $color: nth($state-colors, $i);

  .alert-#{$state} {
    background-color: lighten($color, 40%);
    border-left: 4px solid $color;
    color: darken($color, 20%);
  }

  .badge-#{$state} {
    background-color: $color;
    color: white;
  }

  .text-#{$state} {
    color: $color;
  }
}

Exercise 1: Spacing Utility Generator

Create a comprehensive spacing utility system:

  1. Define a list of spacing values: 0, 4px, 8px, 12px, 16px, 24px, 32px, 48px
  2. Create a list of property types: m (margin), p (padding)
  3. Create a list of directions: t (top), r (right), b (bottom), l (left), x (horizontal), y (vertical)
  4. Generate classes like: .m-0, .mt-4, .px-8, .py-12, etc.
  5. Handle x and y directions properly (x affects left/right, y affects top/bottom)

Exercise 2: Font Family System

Build a type system with interpolation:

  1. Create lists for: font-families (heading-font, body-font, mono-font)
  2. Create lists for: font-weights (light, normal, medium, bold)
  3. Map each font family to an actual font stack (list of fonts)
  4. Generate utility classes: .font-heading, .font-body, .font-mono
  5. Generate weight classes: .font-light, .font-normal, etc.
  6. Create a mixin that accepts both family and weight

Exercise 3: Animation Timing Generator

Create animation timing utilities using lists:

  1. Define a list of timing names: fast, normal, slow
  2. Define a corresponding list of durations: 150ms, 300ms, 600ms
  3. Define a list of easing functions: linear, ease-in, ease-out, ease-in-out
  4. Generate classes: .transition-fast, .transition-normal, .transition-slow
  5. Generate easing classes: .ease-linear, .ease-in, etc.
  6. Create a mixin that combines duration and easing: transition($speed, $easing)

Summary

In this lesson, you mastered:

  • Creating SASS lists with space and comma separators
  • Accessing list items with nth() and checking length with length()
  • Adding items with append() and combining lists with join()
  • Finding items with index() and creating helper functions
  • Iterating through lists with @each to generate CSS
  • String interpolation with #{$variable} syntax
  • Using interpolation in selectors, property names, and values
  • Dynamic media queries with interpolation
  • When to use interpolation vs direct variable references
  • Practical patterns for generating utility classes

Lists and interpolation are powerful tools for creating dynamic, maintainable stylesheets. They enable you to generate repetitive CSS patterns efficiently, build flexible utility systems, and create reusable components that adapt based on configuration. Combined with @each loops, they form the foundation of modern SASS development workflows.