Responsive Advertisement

SASS/SCSS #7: @each in SASS/SCSS

 



Welcome back to series about SASS/SCSS. If you like this content, this is a link for you follow other articles about this topic. Series about SASS/SCSS

In this article, we discuss about @each in SASS/SCSS.

Table of contents:

  • What is @each?
  • @each with list
  • @each with map
  • @each with destructuring
  • Nested @each

Let’s go to the content!

Do we have a list of elements, a map of key, value pairs or we have destructuring that holds multiple values ​​in an element, in many programming languages ​​we have loops like forEach, for, while, do while that allow iterations through the elements in those lists, maps. Similarly, in SASS/SCSS we also have loops like that. So, we already know why we should use loops. Now let's go into how to use them. First, we will learn about @each in SASS/SCSS.

What is @each?

We have a syntax to use @each that is @each <variable> in <expression>. With @each representing whether we want to use @each in iterating list, map or destructuring. Next, <variable> is the name of the variable that represents the values ​​that each element can iterate over. If in a list, each element we can repeat a value, then we name <variable> to represent the value we get. As for a map, we have key and value pairs, we initialize two variables to represent the key and value pairs that we get. Or in the case where we have destructuring with more than two values ​​in an iterable element, we initialize the corresponding number of variables to represent the values ​​an element iterates over. Finally, we have “in <expression>”, <expression> can be a list, map or destructuring and “in” represents whether we use loop in that list, map or destructuring.

@each with list

To better understand the uses of @each in SASS/SCSS, let's look at the following example:

// index.scss

$color-list: red, green, blue;

@each $clr in $color-list {

    .btn-#{$clr} {

        background-color: $clr;

    }

}

 

We have a list of colors, including three colors: red, green, blue. Then we will use @each to iterate over each element in this list. We initialize the variable “$clr” to represent the value that each element iterates and get “in $color-list”. The syntax is quite simple and easy to understand. We perform that task is to get the colors and assign them to "background-color" and the classes will be named according to the name of that color. Let's see what the result we get will be:

/* index.css */

.btn-red {

  background-color: red;

}

 

.btn-green {

  background-color: green;

}

 

.btn-blue {

  background-color: blue;

}

 

The result is exactly what we want, classes "btn" are assigned the name of the color and have a "background-color" of the same color.

@each with map

In the above problem, we use @each to iterate through the list of colors to, using colors. However, if to change those colors to hex, rgb, hsl color codes, the above case is no longer accurate, and we will get an error in SASS/SCSS compiling the code for us. To solve the above problem and another feature of SASS/SCSS, we use a map containing key, value pairs with key being the name of color and value being the value of color which can be hex code, rgb, hsl. And let's see an example how to use @each to traverse each element in a map:

// index.scss

$color-map: (

    primary-clr: #345,

    secondary-clr: #897,

    accent-clr: #456

);

@each $key, $value in $color-map {

    .btn-#{$key} {

        background-color: $value;

    }

}

 

We have a map named “$color-map”, we use @each to start iterating map. We initialize two variables that are $key, $value corresponding to the value that each element has. Then we use $key in the class name and $value will be the value for the background-color property, let's see what the result will be.:

/* index.css */

.btn-primary-clr {

  background-color: #345;

}

 

.btn-secondary-clr {

  background-color: #897;

}

 

.btn-accent-clr {

  background-color: #456;

}

 

Completely consistent with the requirements we have set out. So we can get the setting of variables that match the values ​​in the list or map, making it easy to retrieve the values.

@each with destructuring

Not stopping there, @each also helps us do more difficult things. Let's come to the example of destructuring. No longer limited to key-value pairs only. But we can also initialize more variables to get more value in an element.

// index.scss

$color-destructuring:

    primary-clr #345 #eee 18px,

    secondary-clr #897 #fff 20px,

    accent-clr #456 #fef 17px

;

@each $name, $bg-clr, $clr, $font-size in $color-destructuring {

    .btn-#{$name} {

        background-color: $bg-clr;

        color: $clr;

        font-size: $font-size;

    }

}

 

In the example above we have a destructuring named “$color-destructuring” with 4 values ​​in a word part. We have name, background-color, color, font-size. Every time @each iterates over an element we get the above four values, we initialize four variables that can represent each value we get, and we get the result:

/* index.css */

.btn-primary-clr {

  background-color: #345;

  color: #eee;

  font-size: 18px;

}

 

.btn-secondary-clr {

  background-color: #897;

  color: #fff;

  font-size: 20px;

}

 

.btn-accent-clr {

  background-color: #456;

  color: #fef;

  font-size: 17px;

}

 

Awesome! Not only can we iterate through elements with keys and values, but we can also traverse by destructuring with more values ​​in an element, this value will depend on you defining a destructuring, maybe an element will contain three, four or more values, if you can control them well. So, we've seen how @each works. However, there will be a case in destructuring that happens, that is when we name the variables that represent the values, ​​we can traverse that do not match the number we get.?

// index.scss

$color-destructuring:

    primary-clr #345 #eee 18px,

    secondary-clr #897 #fff 20px,

    accent-clr #456 #fef 17px

;

@each $name, $bg-clr, $font-size in $color-destructuring {

    .btn-#{$name} {

        background-color: $bg-clr;

        font-size: $font-size;

    }

}

 

We use the above example again and we see that, we omit the $color value and we just take the value of $font-size, let's see the value we get will be:

/* index.css */

.btn-primary-clr {

  background-color: #345;

  font-size: #eee;

}

 

.btn-secondary-clr {

  background-color: #897;

  font-size: #fff;

}

 

.btn-accent-clr {

  background-color: #456;

  font-size: #fef;

}

 

Wow! The result we get is that the values ​​are taken in turn, although we intentionally omit a value, however, the SASS/SCSS compiler still takes consecutive values. Likewise, if we initialize more variables than we retrieve, what will be the result?

// index.scss

$color-destructuring:

    primary-clr #345 #eee 18px,

    secondary-clr #897 #fff 20px,

    accent-clr #456 #fef 17px

;

@each $name, $bg-clr, $clr, $font-size, $space in $color-destructuring {

    .btn-#{$name} {

        background-color: $bg-clr;

        color: $clr;

        font-size: $font-size;

        padding: $space;

    }

}

 

In the above example, we have taken out a variable $space and we set the property as padding. Let's see the results we get when we have absolutely no value.

/* index.css */

.btn-primary-clr {

  background-color: #345;

  color: #eee;

  font-size: 18px;

}

 

.btn-secondary-clr {

  background-color: #897;

  color: #fff;

  font-size: 20px;

}

 

.btn-accent-clr {

  background-color: #456;

  color: #fef;

  font-size: 17px;

}

 

Nothing happened. So, we already know that when setting the variable variable, @each will take turns, when we set the excess, the values ​​will be taken just enough with the value we have set.

Nested @each

The problem will become a little more complicated, we no longer must deal with a map, we will deal with a nested map. And let's see how we will handle the nested map?

// index.scss

$color-map: (

    danger: (

        color: orange,

        background-color: red,

    ),

    success: (

        color: green,

        background-color: green

    )    

);

 

@each $key, $value in $color-map {

    .btn-#{$key} {

        @each $k, $v in $value {

            #{$k}: #{$v}

        }

    }

}

 

In the above example we have a parent map of “$color-map”, this map contains child maps as danger, success as modifiers. We use the @each loop for the parent map, we get the key, value pairs. We can predict that the key will be “danger”, “success” and the value will be the values ​​of the child maps. We use the keys obtained from the parent map to name the class. And use value as a child map to make properties for these classes. Let's see what the result will be:

/* index.css */

.btn-danger {

  color: orange;

  background-color: red;

}

 

.btn-success {

  color: green;

  background-color: green;

}

 

Awesome! Both @each work well and using nested map still meets our needs.

Conclusion

We just went through an analysis of @each in SASS/SCSS. We already know the basic syntax of @each. Applying @each in iterating lists, maps or more difficult is destructuring. Besides that, we've covered other exceptions and nested @each.

If you have any ideas, feel free to comment below. Thank you for joining with me. Having a good day!


Đăng nhận xét

0 Nhận xét