Sass list.zip()

Beginner
11 min read
Updated: Nov 2026
5 examples
Dart Sass 1.23+

Definition and Usage

list.zip($lists...) combines every list in $lists into a single list of sublists. Each sublist holds the items at that position across the inputs. Load it with @use "sass:list" on Dart Sass 1.23+ (global zip() still works).

Official samples.

list.zip(10px 50px 100px, short mid long) → 10px short, 50px mid, 100px long. Shorter second list: list.zip(10px 50px 100px, short mid) → 10px short, 50px mid.

Separators are fixed.

The outer list is always comma-separated. Each inner sublist is always space-separated—regardless of the input separators.

Shortest list wins.

The result is as long as the shortest input. Extra items on longer lists are dropped—align lengths when every pair matters.

Syntax

SCSS
@use "sass:list";

list.zip(10px 50px 100px, short mid long);
// 10px short, 50px mid, 100px long

list.zip(10px 50px 100px, short mid);
// 10px short, 50px mid

list.zip(1 2 3, a b c, x y z);
// 1 a x, 2 b y, 3 c z

Pattern: build parallel token lists → list.zip → loop with @each or read pairs with list.nth.

How Zip Pairs

Keep these rules in mind when shaping token lists:

RuleDetail
Position pairingIndex 1 of each list → first sublist; index 2 → second; …
Result lengthEqual to the shortest input list
Outer separatorAlways comma
Inner separatorAlways space
ArityVariadic—two, three, or more lists
Empty inputZipping an empty list yields an empty result
Maps count as lists.

Every map is a list of key/value pairs, so list helpers—including zip—also apply to maps when that shape fits your data.

SCSS Examples

Examples target Dart Sass 1.23+ with @use "sass:list". Open View Compiled CSS for verified output (matches official Sass docs samples).

Example 1 — Pair Two Lists (Official Docs)

Sizes and names meet at each index.

SCSS
@use "sass:list";

@debug list.zip(10px 50px 100px, short mid long);
// 10px short, 50px mid, 100px long

$pairs: list.zip(10px 50px 100px, short mid long);

.sizes {
  --zip: #{$pairs};
  --len: #{list.length($pairs)};
  --sep: #{list.separator($pairs)};
  --inner-sep: #{list.separator(list.nth($pairs, 1))};
  --first: #{list.nth($pairs, 1)};
}

How It Works

  1. Three + three inputs produce three sublists.
  2. Outer separator is comma — confirmed by list.separator.
  3. Each pair is space-separated (for example 10px short).
  4. Matches the official Sass docs sample.

Example 2 — Shortest List Wins (Official Docs)

Extra items on the longer list are ignored.

SCSS
@use "sass:list";

@debug list.zip(10px 50px 100px, short mid);
// 10px short, 50px mid

.short {
  --zip: #{list.zip(10px 50px 100px, short mid)};
  --len: #{list.length(list.zip(10px 50px 100px, short mid))};
}

How It Works

  1. Second list has length 2, so only two pairs are built.
  2. 100px is dropped — no partner remains.
  3. Align lengths when every token must appear.
  4. Matches the official shortest-list sample.

Example 3 — Zip Three Lists

Each sublist grows to one value from every input.

SCSS
@use "sass:list";

$triples: list.zip(1 2 3, a b c, x y z);

.three {
  --zip: #{$triples};
  --second: #{list.nth($triples, 2)};
}

How It Works

  1. Three inputs → each sublist has three space-separated items.
  2. Index 2 is 2 b y.
  3. Same shortest rule applies across all inputs.
  4. Useful when you need size + name + modifier together.

Example 4 — Utility Classes with @each

Destructure each space-separated pair while looping.

SCSS
@use "sass:list";

@each $size, $name in list.zip(10px 20px 30px, sm md lg) {
  .pad-#{$name} {
    padding: $size;
  }
}

How It Works

  1. Zip builds 10px sm, 20px md, 30px lg.
  2. @each destructures each space pair into $size and $name.
  3. Interpolation builds class names like .pad-sm.
  4. Keep lists aligned so every utility gets a value.

Example 5 — Zip Property Names and Values

Drive multiple declarations from parallel token lists.

SCSS
@use "sass:list";

$props: (margin, padding, gap);
$vals: (8px, 12px, 16px);

@each $prop, $val in list.zip($props, $vals) {
  .box {
    #{$prop}: $val;
  }
}

How It Works

  1. Comma lists still zip position-by-position.
  2. Inner pairs become space lists ready for @each.
  3. Property interpolation writes each declaration.
  4. Note: Sass emits one .box rule per iteration—fine for teaching; merge manually if you need a single block.

Edge Cases & Pitfalls

Most zip bugs are mismatched lengths or assuming input separators are preserved.

length

Shortest list truncates

Compare list.length on each input before zipping when every item must pair.

sep

Separators are rewritten

Result is always comma outside / space inside—even if you started with slash or brackets.

empty

Empty list → empty zip

list.zip((), a b c) returns (). Guard before looping.

flat

CSS flattens nested structure

In custom properties the pairs look flat. Use list.nth / list.length (or meta.inspect) when you need structure.

Sass Support

Prefer the module form with a current Dart Sass release. Global zip() remains for older call sites.

APIStatus
list.zip()Dart Sass 1.23+ via @use "sass:list"
Global zip()Available; prefer module form in new code
Return typeComma list of space-separated sublists
LibSass / Ruby SassNo modern sass:list module—use global zip() if needed

Compile with the Dart Sass CLI.

Key Takeaways

  • Pairs by position across two or more lists.
  • Shortest list sets the length — extras are dropped.
  • Comma outside, space inside every time.
  • Great with @each for utility and token loops.

One line: when parallel token lists need pairing, call list.zip($a, $b, …).

Compile Notes

Practical checklist:

checklist.txt
1. @use "sass:list"
2. Keep parallel lists the same length when every pair matters
3. Remember: outer comma, inner space
4. Loop with @each $a, $b in list.zip(...)
5. Confirm length/separator with list.length / list.separator

Frequently Asked Questions

list.zip($lists...) combines parallel lists into one list of sublists. Each sublist holds the items at that position across the inputs. Example: list.zip(10px 50px 100px, short mid long) is 10px short, 50px mid, 100px long.
Official docs: the returned list is as long as the shortest list. Extra items on longer lists are dropped.
The returned list is always comma-separated. Each inner sublist is always space-separated—regardless of the input separators.
Yes. Pass as many lists as you need. Each sublist contains one value from each input at that index.
Because each sublist is space-separated, you can destructure: @each $size, $name in list.zip($sizes, $names) { ... }.
Built-in modules with @use need Dart Sass 1.23+. LibSass and Ruby Sass do not load sass:list the same way—use the global zip() name there if you must.

Next: Sass map.deep-merge()

Recursively merge nested maps in the sass:map module.

map.deep-merge() →

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.

8 people found this page helpful