Sass Lists

Beginner
⏱️ 14 min read
📚 Updated: Jul 2026
🎯 5 Examples
Sequences of values

What You’ll Learn

Sass lists hold a sequence of values. This page covers separators, brackets, 1-based indexes, nth / append / index, @each, immutability, argument lists, and five compiled examples.

01

Separators

space / comma

02

Brackets

[ … ]

03

Indexes

Start at 1

04

@each

Loop items

05

Immutable

append returns new

06

Practice

5 examples

What Are Sass Lists?

Official docs: lists contain a sequence of other values. Elements can be separated by commas (Helvetica, Arial, sans-serif), spaces (10px 15px 0 0), or slashes—as long as the separator is consistent within the list.

Unlike many languages, Sass lists do not require brackets. Any expressions separated with spaces or commas count as a list. Square brackets ([line1 line2]) are allowed and especially useful for values like grid-template-columns.

  • Use parentheses to nest lists or disambiguate separators.
  • Single values act like one-element lists for most list functions.
  • Empty unbracketed () is not valid CSS in a property value.
  • Indexes start at 1; -1 is the last item.
💡
Beginner tip

Think of a Sass list as a CSS value that already looks like a sequence—font stacks, padding shorthands, or grid tracks—then use sass:list when you need to read or build those sequences in code.

📝 Syntax

styles.scss
$space: 10px 12px 16px;                 // space-separated
$comma: Helvetica, Arial, sans-serif;   // comma-separated
$lines: [line1, line2, line3];          // bracketed
$nested: (1, 2), (3, 4);                // list of lists

➗ Slash-Separated Lists

Official docs: slash-separated lists represent values like font: 12px/30px or modern color alpha syntax. Because / historically meant division, you cannot reliably write slash lists as literals today. Create them with list.slash() while stylesheets migrate to math.div().

styles.scss
@use "sass:list";

$font-shorthand: list.slash(12px, 30px); // 12px / 30px

🧮 Using Lists

Load @use "sass:list" for helpers. Common ones:

NeedFunction
Get item nlist.nth($list, $n)
Add to the endlist.append($list, $val)
Find positionlist.index($list, $value)
Count itemslist.length($list)
Space vs commalist.separator($list)

Loop with @each: @each $item in $list { … }.

🔒 Immutability

Official docs: Sass lists never change in place. list.append and friends return new lists. That avoids sneaky bugs when the same list is shared. To grow a collection, reassign: $prefixes: list.append($prefixes, $next);

📦 Argument Lists

When a mixin or function takes arbitrary arguments with $args..., you get a special argument list. It behaves like a normal list of positional values, and keyword arguments are available as a map via meta.keywords($args).

⚡ Quick Reference

GoalCode
Space list10px 12px 16px
Comma listHelvetica, Arial, sans-serif
Bracketed[line1, line2]
2nd itemlist.nth($list, 2)
Last itemlist.nth($list, -1)
Appendlist.append($list, $val)
Validate membership@if not list.index($allowed, $val)
Slash listlist.slash(12px, 30px)

Examples Gallery

Each example shows a common list pattern. Open View Compiled CSS for verified output.

📚 Getting Started

Read items, detect separators, and generate utilities.

Example 1 — nth, Length & Separators

Pull items by index and inspect how a list is separated.

styles.scss
@use "sass:list";
@use "sass:meta";

$fonts: Helvetica, Arial, sans-serif;
$space: 10px 12px 16px;
$lines: [line1, line2, line3];

.lists {
  --nth: #{meta.inspect(list.nth($space, 2))};
  --last: #{meta.inspect(list.nth($lines, -1))};
  --len: #{meta.inspect(list.length($space))};
  --sep-space: #{meta.inspect(list.separator($space))};
  --sep-comma: #{meta.inspect(list.separator($fonts))};
  --bracketed: #{meta.inspect(list.is-bracketed($lines))};
}

How It Works

Index 2 is the second item. -1 is the last. list.separator reports space or comma.

Example 2 — Loop a List with @each

Official-docs style icon size utilities from a comma-separated list.

styles.scss
$sizes: 40px, 50px, 80px;

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

How It Works

Each length becomes $size once. Add a size to the list and Sass writes the matching utility class automatically.

📈 Append, Validate & Collect

Immutability, membership checks, slash lists, and keyword args.

Example 3 — append Returns a New List

Grow a space list and a bracketed grid-line list without mutating the original.

styles.scss
@use "sass:list";
@use "sass:meta";

$base: 10px 12px 16px;
$with-extra: list.append($base, 25px);
$grid: list.append([col1-line1], col1-line2);

.append-demo {
  --base: #{meta.inspect($base)};
  --extra: #{meta.inspect($with-extra)};
  --grid: #{meta.inspect($grid)};
}

How It Works

$base is unchanged after append. The new value lives in $with-extra. Bracketed lists keep their brackets in the result.

Example 4 — Validate with list.index

Find positions in a shorthand list, and guard mixin arguments with @error.

styles.scss
@use "sass:list";
@use "sass:meta";

$valid-sides: top, bottom, left, right;

@mixin attach($side) {
  @if not list.index($valid-sides, $side) {
    @error "#{$side} is not a valid side. Expected one of #{$valid-sides}.";
  }

  border-#{$side}: 2px solid currentColor;
}

.box {
  @include attach(left);
}

.check {
  --i1: #{meta.inspect(list.index(1px solid red, 1px))};
  --i2: #{meta.inspect(list.index(1px solid red, solid))};
  --missing: #{meta.inspect(list.index(1px solid red, dashed))};
}

How It Works

A miss returns null (falsey), so @if not list.index(…) is a clean membership test before emitting CSS.

Example 5 — Collect Prefixes, Slash Lists & Keyword Args

Build a list in a loop, create a slash list, and expand keyword argument maps.

styles.scss
@use "sass:list";
@use "sass:map";
@use "sass:meta";

$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);

@function prefixes-for-browsers($browsers) {
  $prefixes: ();
  @each $browser in $browsers {
    $prefixes: list.append($prefixes, map.get($prefixes-by-browser, $browser));
  }
  @return $prefixes;
}

@mixin syntax-colors($args...) {
  @each $name, $color in meta.keywords($args) {
    pre span.stx-#{$name} {
      color: $color;
    }
  }
}

.demo {
  --pfx: #{meta.inspect(prefixes-for-browsers("firefox" "ie"))};
  --slash: #{meta.inspect(list.slash(12px, 30px))};
}

@include syntax-colors(
  $string: #080,
  $comment: #800,
  $variable: #60b,
);

How It Works

Reassigning $prefixes accumulates values because lists are immutable. meta.keywords($args) turns named mixin arguments into a map for @each.

🚀 Real-World Use Cases

  • Utility generators — sizes, spacings, or breakpoints in one list.
  • Font stacks — comma-separated family lists.
  • Grid tracks — bracketed line-name lists.
  • Validation — allow-lists checked with list.index.
  • Flexible mixins$args... plus meta.keywords.

🧠 How Compilation Works

1

Parse the sequence

Detect space, comma, slash, brackets, and nesting.

Parse
2

Read or build

Use nth / append / index, or walk items with @each.

Work
3

Emit CSS

Write separators and brackets the way CSS expects.

Serialize
4

CSS ships

Browsers see plain sequences—Sass list APIs stay compile-time.

⚠️ Common Pitfalls

  • 0-based indexes — Sass lists start at 1.
  • Expecting mutationappend does not change the original list.
  • Empty () in CSS — unbracketed empty lists are invalid property values.
  • Comma lists as arguments — wrap with extra parentheses when passing one list to a function.
  • Writing slash lists literally — use list.slash() instead of relying on /.

💡 Best Practices

✅ Do

  • Keep separator style consistent inside one list
  • Use @use "sass:list" for nth / append / index
  • Prefer @each when generating repetitive CSS
  • Reassign when accumulating: $list: list.append(…)
  • Use bracketed lists for grid line names

❌ Don’t

  • Assume indexes start at 0
  • Ignore a null from list.index when validating
  • Put empty unbracketed lists into CSS properties
  • Mix spaces and commas in the same list
  • Treat slash / as a literal list separator in source

Key Takeaways

Knowledge Unlocked

Five things to remember about Sass lists

Sequences with separators, 1-based indexes, and immutable helpers.

5
Core concepts
🔢 02

Indexes

start at 1

API
🔄 03

@each

loop items

Generate
🔒 04

Immutable

append = new

Safety
05

$args...

argument lists

Mixins

❓ Frequently Asked Questions

A list is a sequence of values. Elements can be separated by spaces, commas, or slashes (slash lists are created with list.slash()). Brackets like [a b] are optional but useful for CSS Grid.
No. Index 1 is the first element. Negative indexes count from the end: -1 is the last element.
No. Lists are immutable. Functions like list.append() return a new list; they do not change the original. Reassign the variable if you need to update state.
Use @each $item in $list { … }. Each element is assigned to $item once per iteration.
It returns null, which is falsey—so you can use it with @if to validate allowed values.
When a mixin or function uses $args..., the collected arguments form a special list. Keyword arguments are available via meta.keywords($args).
Did you know?

Official Sass docs note that individual non-list values are treated as one-element lists by list functions—so you rarely need to wrap a single value just to call list.nth or list.append.

Conclusion

Sass lists are CSS-friendly sequences with space, comma, or slash separators. Read them with nth, grow them with append, validate with index, and generate styles with @each—always remembering lists are immutable.

Continue with Sass Maps or @each.

Next: Sass Maps

Learn key/value tokens with map.get, set, merge, and @each.

Sass Maps →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful