Sass/SCSS for, each & while loops (Iteration Control) Tutorial
In this Sass/SCSS tutorial we learn how to control the flow of our script and repeat sections of code with loops.
We cover the @for loop that runs a set number of times, the @while loop that runs with a condition and the @each loop that iterates through list and map collections.
Lastly we discuss when to use which loop.
What is iteration control and looping
Sass allows us to control the flow of our scripts even further by looping through sections of code, executing that process on each iteration.
Sass provides us with three different kinds of loops.
- @for - This loop iterates through a section of code for a set number of times.
- @while - This loop iterates through a section of code while a condition is true.
- @each - This loop iterates through all elements in a collection without a condition.
The @for loop
The for loop will iterate through a section of code for a specified number of times.
A for loop consists of 3 parts.
- The counter variable to keep track of the current iteration.
- The number to start looping from.
- The number to loop to.
We start with the @for rule, followed by the counter variable. Then we use the from keyword and the number to start looping from.
Finally we use the through keyword and specify the number that we want to loop to, followed by a code block.
@for $counter from number through number {
// code to execute on each loop
}
The counter variable is not initialized with a value like in other programming languages, it will receive its value from the starting number.
The statement reads: for current iteration from beginning to end, execute code
$font-size: (24px, 22px, 20px, 18px);
@for $i from 1 through 4 {
h#{$i} {
font-size: nth($font-size, $i);
}
}
In the example above we want to create 4 heading styles with the font sizes from the list, so we iterate from 1 through 4 with $i as our counter variable.
In the code block we create a h element with the counter as the heading number. We use the counter again to get the font size out of the list into the property.
With each iteration, the counter will increase and both add the number to the h, as well as assigning the correct element value to the property.
h1 {
font-size: 24px;
}
h2 {
font-size: 22px;
}
h3 {
font-size: 20px;
}
h4 {
font-size: 18px;
}
We can also use the to keyword in the loop if we want to exclude the last iteration.
$font-size: (24px, 22px, 20px, 18px);
@for $i from 1 to 4 {
h#{$i} {
font-size: nth($font-size, $i);
}
}
This time the loop will only run 3 times because it will exclude the last iteration.
h1 {
font-size: 24px;
}
h2 {
font-size: 22px;
}
h3 {
font-size: 20px;
}
The @while loop
The while loop includes a conditional block. If the evaluation proves true it will continue looping through a section of code until the condition proves false.
We start with the @while rule, followed by the condition to evaluate and a code block.
@while condition {
// code to execute on each loop
}
The statement reads: while condition is true, execute code
$font-size: 16;
@while $font-size <= 24 {
.font-size-#{$font-size} {
font-size: #{$font-size}px;
line-height: #{$font-size + 2}px;
}
// Increment the counter
$font-size: $font-size + 2;
}
In the examples above we want to create a class for each even number from 16 to 24 with a font-size and line height. Before the loop ends, we increment the $font-size counter to advance the loop.
If we don’t increment the counter, the condition will always stay true and the loop will continue running until Node crashes.
.font-size-16 {
font-size: 16px;
line-height: 18px;
}
.font-size-18 {
font-size: 18px;
line-height: 20px;
}
.font-size-20 {
font-size: 20px;
line-height: 22px;
}
.font-size-22 {
font-size: 22px;
line-height: 24px;
}
.font-size-24 {
font-size: 24px;
line-height: 26px;
}
note The @while loop is only really used in very complex situations. In most cases the @for or @each loop will be enough and should be favored above @while . They also compile faster.
The @each loop
The each loop will iterate over items in a collection from the beginning to the end.
It doesn’t have a conditional block like @while , and we cannot specify the amount of times the loop should run like @for .
The each loop will start at the first element in the list or map and continue until it reaches the last element.
note The @each loop is similar to the foreach loop in other programming languages like C# , PHP and Java .
We start with the @each rule, followed by a temporary variable that we will use to access the element value.
Then we use the in keyword, followed by the collection we want to iterate over and a code block.
@each temp_variable in list {
// code to execute on each loop
}
The statement reads: for each element in list, execute code
$font-sizes: (16, 18, 20, 22);
@each $size in $font-sizes {
.font-size-#{$size} {
font-size: #{$size}px;
line-height: #{$size + 2}px;
}
}
In the examples above we create our font classes again. We use the $size temporary variable to access the value of the list in the current iteration.
.font-size-16 {
font-size: 16px;
line-height: 18px;
}
.font-size-18 {
font-size: 18px;
line-height: 20px;
}
.font-size-20 {
font-size: 20px;
line-height: 22px;
}
.font-size-22 {
font-size: 22px;
line-height: 24px;
}
@for vs @while vs @each
All three loops will, with some modification, be able to do whatever iteration control you need. That said, each loop is better suited to certain tasks than others.
- The @for loop is typically used when we need our loop to run a specific number of times.
- The @while loop is typically used when the amount of times the loop will run is unknown, and based on a condition.
- The @each loop is typically used to iterate over items in a list or map collection.
Summary: Points to remember
- Iteration control allows to control the flow of our script by using loops to execute sections of code repeatedly.
- The @for loop repeats code for a set number of times.
- We need to specify the start and end numbers with the from and to/through keywords.
- The @while loop repeats code while a condition remains true.
- The @each loop repeats code for each element in a list or map collection.