Sass list.zip() Function

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
sass:list · Dart Sass 1.23+

What You’ll Learn

list.zip() belongs to the built-in sass:list module. It pairs items from parallel lists into sublists. This page covers shortest-list length, comma vs space separators, looping with @each, Dart Sass support, and five compiled examples.

01

Concept

Pair parallel lists

02

Module

@use "sass:list"

03

Length

Shortest wins

04

Separators

Comma outer / space inner

05

Pair with

@each + nth

06

Practice

5 examples

What Is list.zip()?

Imagine two columns of sticky notes: sizes on the left, names on the right. Zipping them stacks each row into a small pair—10px short, 50px mid, and so on. That is what list.zip does at compile time.

  • 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 (shortest wins)
💡
Beginner tip

Think of a zipper on a jacket: teeth from both sides meet one-by-one. Extra teeth on a longer side are left behind when the other side ends.

📝 Syntax

Load the list module, then pass two or more lists:

styles.scss
@use "sass:list";

list.zip($lists...)

Parameters

ParameterTypeRequiredDescription
$lists...Lists (variadic)Yes (two or more typical)The parallel lists to combine. Each position becomes one sublist.

Return value

TypeResult
ListA comma-separated list of space-separated sublists, as long as the shortest input

📦 Loading sass:list

styles.scss
// Recommended — namespaced
@use "sass:list";
$pairs: list.zip(10px 50px, short mid);

// Optional — bring members into scope
@use "sass:list" as *;
$pairs: zip(10px 50px, short mid);

// Optional — custom namespace
@use "sass:list" as l;
$pairs: l.zip(10px 50px, short mid);
⚠️
Put @use first

Keep @use "sass:list"; near the top of the file, before most other rules.

🔍 Separators: Comma Outside, Space Inside

Official docs fix the structure of the result. Input separators do not change that shape.

styles.scss
@use "sass:list";

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

list.separator($z);              // comma
list.separator(list.nth($z, 1)); // space
// first pair → 10px short

📋 list.zip vs list.join

list.ziplist.join
QuestionPair items by positionConcatenate into one flat list
ShapeList of sublistsOne list of values
Length ruleShortest inputSum of both lengths
Typical use@each over pairsMerge scales / stacks

🛠 Compatibility

This is about Sass compilers, not browsers. Compiled CSS only contains the finished utilities or values you emit from the zipped pairs.

Implementation@use "sass:list"Global zip()
Dart Sass (1.23+)Yes — preferredYes
LibSassNo built-in modulesYes (legacy)
Ruby SassNo built-in modulesYes (legacy)

⚡ Quick Reference

GoalCode
Import list@use "sass:list";
Zip two listslist.zip(10px 50px 100px, short mid long)
Unequal lengthsResult length = shortest list
Read a pairlist.nth($pairs, 1) → space sublist
Loop pairs@each $pair in $pairs { … }
Legacy globalzip($lists...)

Examples Gallery

Each example uses @use "sass:list". Open View Compiled CSS for verified Dart Sass output (official samples where noted).

📚 Getting Started

Official docs samples for equal and unequal lengths.

Example 1 — Zip Equal and Unequal Lists (Official Docs)

Pair sizes with names; see the shortest-list rule and separators.

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

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

.zip {
  --a: #{meta.inspect(list.zip(10px 50px 100px, short mid long))};
  --b: #{meta.inspect(list.zip(10px 50px 100px, short mid))};
  --sep: #{meta.inspect(list.separator(list.zip(10px 50px 100px, short mid long)))};
  --inner: #{meta.inspect(list.separator(list.nth(list.zip(10px 50px 100px, short mid long), 1)))};
}

How It Works

Equal lengths yield three pairs. When names stop at mid, the third size is dropped. Outer separator is comma; each pair is space-separated.

Example 2 — Generate Gap Utilities with @each

Zip sizes to class-name tokens, then emit margin rules.

styles.scss
@use "sass:list";

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

@each $pair in $pairs {
  .gap-#{list.nth($pair, 2)} {
    margin: list.nth($pair, 1);
  }
}

How It Works

Each $pair is a two-item space list. Index 1 is the size; index 2 becomes the class suffix.

📈 Practical Patterns

Theme maps, three-way zips, and font/weight pairs.

Example 3 — Zip Role Names with Colors

Build swatch classes from parallel role and color lists.

styles.scss
@use "sass:list";

$colors: #336699 #e67e22 #94a3b8;
$roles: primary accent muted;
$theme: list.zip($roles, $colors);

@each $pair in $theme {
  .swatch-#{list.nth($pair, 1)} {
    background: list.nth($pair, 2);
  }
}

How It Works

Roles and colors stay in separate source lists, but zip keeps them aligned so you can loop one structure instead of managing two indexes by hand.

Example 4 — Zip Three Lists (Shortest Wins)

With three inputs, each sublist has three items—until the shortest list ends.

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

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

.three {
  --len: #{list.length($z)};
  --all: #{meta.inspect($z)};
}

How It Works

$b only has two items, so the result length is 2. Values 3, 4, and z are unused.

Example 5 — Pair Font Families with Weights

Inspect zipped font/weight pairs before using them in mixins.

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

$fonts: Helvetica Arial;
$weights: 400 700;
$fw: list.zip($fonts, $weights);

.card {
  --pair1: #{meta.inspect(list.nth($fw, 1))};
  --pair2: #{meta.inspect(list.nth($fw, 2))};
}

How It Works

Each pair is ready for list.nth($pair, 1) (family) and list.nth($pair, 2) (weight) inside a loop or mixin.

🚀 Real-World Use Cases

  • Utility generators — zip values to class-name tokens.
  • Design tokens — keep parallel role/color or size/label lists aligned.
  • Mixin APIs — accept two lists and iterate one zipped structure.
  • Multi-column data — zip three or more related lists into rows.
  • Safe pairing — shortest-list rule avoids out-of-range indexes.

🧠 How Compilation Works

1

Write SCSS

Call list.zip($list1, $list2, …) after @use "sass:list".

Source
2

Pair by position

Dart Sass builds one sublist per index until the shortest list ends.

Compile
3

Return structured pairs

You get a comma list of space sublists for @each or nth.

Result
4

CSS sees your utilities

No zip call remains—only the finished classes or properties you emitted.

⚠️ Common Pitfalls

  • Silent truncation — longer lists lose trailing items without an error.
  • Expecting input separators — output is always comma outer / space inner.
  • Confusing with join — join flattens; zip builds pairs.
  • Forgetting @uselist.zip needs sass:list.
  • Misreading sublists — use list.nth($pair, 1) / 2 inside @each.

💡 Best Practices

✅ Do

  • Use @use "sass:list" and list.zip() in new SCSS
  • Keep parallel lists the same length when every item matters
  • Loop with @each $pair in list.zip(...)
  • Read pair slots with list.nth
  • Prefer Dart Sass for built-in modules

❌ Don’t

  • Expect the browser to evaluate list.zip
  • Assume unequal lists will error
  • Use zip when you meant list.join
  • Rely on LibSass for @use "sass:list"
  • Forget that inner pairs are space-separated

Key Takeaways

Knowledge Unlocked

Five things to remember about list.zip()

Pair by position—shortest wins; comma list of space pairs.

5
Core concepts
📦 02

Module

sass:list

@use
🔢 03

Length

shortest input

Rule
04

Shape

comma → space pairs

Safe
05

Prefer

Dart Sass 1.23+

Tooling

❓ 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 ignored.
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 will contain one value from each input at that index.
Yes. Global zip($lists...) still works. New projects should prefer list.zip() after @use "sass:list".
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.
Did you know?

Maps already behave like lists of key/value pairs in Sass. If your data is naturally a map, prefer sass:map helpers. Use list.zip when you start from separate parallel lists instead.

Conclusion

list.zip() pairs parallel Sass lists into comma-separated rows of space-separated values. Load it through sass:list, remember the shortest-list rule, and drive utilities with @each plus list.nth.

Continue with map.deep-merge() or explore list.join().

Next: map.deep-merge()

You finished the list helpers—next, recursively merge nested maps with map.deep-merge().

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.

5 people found this page helpful