Lists & Interpolation
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);
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
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
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!
// }
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
}
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:
- Define a list of spacing values: 0, 4px, 8px, 12px, 16px, 24px, 32px, 48px
- Create a list of property types: m (margin), p (padding)
- Create a list of directions: t (top), r (right), b (bottom), l (left), x (horizontal), y (vertical)
- Generate classes like: .m-0, .mt-4, .px-8, .py-12, etc.
- 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:
- Create lists for: font-families (heading-font, body-font, mono-font)
- Create lists for: font-weights (light, normal, medium, bold)
- Map each font family to an actual font stack (list of fonts)
- Generate utility classes: .font-heading, .font-body, .font-mono
- Generate weight classes: .font-light, .font-normal, etc.
- Create a mixin that accepts both family and weight
Exercise 3: Animation Timing Generator
Create animation timing utilities using lists:
- Define a list of timing names: fast, normal, slow
- Define a corresponding list of durations: 150ms, 300ms, 600ms
- Define a list of easing functions: linear, ease-in, ease-out, ease-in-out
- Generate classes: .transition-fast, .transition-normal, .transition-slow
- Generate easing classes: .ease-linear, .ease-in, etc.
- 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.