Lists in Sass: syntax and use cases with examples

Sass lists are ordered collections of values, similar to arrays in other languages.

Lists fit naturally into CSS because values such as 10px 15px 0 0 and Helvetica, Arial, sans-serif are already lists. Sass adds functions and loops for reading and transforming them.

Defining a list

A space-separated list needs no brackets:

$horse-types: pony horse mini-horse maxi-pony;

Lists can also use commas:

$horse-types: pony, horse, mini-horse, maxi-pony;

Quote an item when spaces must remain part of that single value. Without the quotes, mini horse would be two items:

$horse-types: 'pony', 'horse', 'mini horse', 'maxi pony';

Lists can be nested. Here, commas separate the outer list and spaces separate each name-and-color pair:

$horses: (pony #996633), (horse #fff), (mini-horse #333), (maxi-pony #cc9849);

Parentheses group each inner list. Square brackets are also allowed, which is useful for CSS Grid line names:

$grid-lines: [main-start] 1fr [content-start] 2fr [main-end];

See the Sass documentation for the full list syntax.

Noteworthy things about lists

  • Indexes start at 1, not 0. Negative indexes count back from the end.
  • List functions treat a single value as a one-item list.
  • Maps also count as lists of key/value pairs.
  • Lists are immutable. Functions return new lists instead of changing the original.

For example:

@use 'sass:list';
 
@debug list.length('Fire Walk with Me'); // 1
@debug list.length(Fire Walk with Me); // 4

List functions

Load the built-in module with @use 'sass:list', then call its functions with the list. namespace. The older global names such as nth() still exist, but the module API makes their origin clear.

FunctionDescription
list.append($list, $value, $separator: auto)Returns a copy with one value added to the end
list.index($list, $value)Returns the first matching index, or null
list.is-bracketed($list)Reports whether the list uses square brackets
list.join($list1, $list2, $separator: auto, $bracketed: auto)Combines two lists
list.length($list)Returns the number of items
list.nth($list, $n)Returns the item at an index
list.separator($list)Returns space, comma, or slash
list.set-nth($list, $n, $value)Returns a copy with one item replaced
list.slash($elements...)Creates a slash-separated list
list.zip($lists...)Combines matching positions into nested lists

See the sass:list reference for details and compatibility notes.

Accessing a list

Use list.nth() to read an item:

@use 'sass:list';
 
$horse-types: pony horse mini-horse maxi-pony;
 
@debug list.nth($horse-types, 1); // pony
@debug list.nth($horse-types, -1); // maxi-pony

Use an @for loop when you need the index as well as the value:

@use 'sass:list';
 
$horse-types: pony horse mini-horse maxi-pony;
 
@for $i from 1 through list.length($horse-types) {
  .horse-#{$i}::after {
    content: '#{$i}. #{list.nth($horse-types, $i)}';
  }
}

When you only need each value, an @each loop is shorter:

$horse-types: pony horse mini-horse maxi-pony;
 
@each $horse in $horse-types {
  .horse-photo--#{$horse} {
    background-image: url('/images/horses/#{$horse}.png');
  }
}

Accessing nested lists

Consider the name-and-color pairs from earlier:

$horses: (pony #996633), (horse pink), (mini-horse #333), (maxi-pony #cc9849);

Each pass through the loop gives us one inner list. We can access its two items with list.nth():

@use 'sass:list';
 
@each $horse in $horses {
  $name: list.nth($horse, 1);
  $color: list.nth($horse, 2);
 
  .horse--#{$name} {
    background-color: $color;
    background-image: url('/images/horses/#{$name}.png');
  }
}

The two levels look like this:

$horses

  ├─ $horse: pony #996633
  │           │       │
  │           │       └─ list.nth($horse, 2) → #996633
  │           └───────── list.nth($horse, 1) → pony

  ├─ $horse: horse pink
  ├─ $horse: mini-horse #333
  └─ $horse: maxi-pony #cc9849

An @each loop can destructure the inner lists, so this is usually simpler:

@each $name, $color in $horses {
  .horse--#{$name} {
    background-color: $color;
    background-image: url('/images/horses/#{$name}.png');
  }
}

Adding to a list

Use list.append() to return a new list with one value added:

@use 'sass:list';
 
$horse-types: pony horse mini-horse maxi-pony;
$horse-types: list.append($horse-types, shetland);
 
@debug $horse-types; // pony horse mini-horse maxi-pony shetland

The reassignment matters because the original list cannot be changed. Pass $separator: comma, $separator: space, or $separator: slash when the result needs a specific separator:

$horse-types: list.append($horse-types, mustang, $separator: comma);

Use list.join() instead when combining two complete lists.

Lists or maps?

Lists work well for ordered values, repeated variants, and arguments that map directly to CSS:

$card-corners: 1rem 1rem 0 0;
 
.card {
  border-radius: $card-corners;
}

If each value has a name, a map usually communicates the structure better than a nested list:

$horse-colors: (
  pony: #996633,
  horse: pink,
  mini-horse: #333,
  maxi-pony: #cc9849,
);
 
@each $name, $color in $horse-colors {
  .horse--#{$name} {
    background-color: $color;
  }
}