Looping Through Two @Each Lists in SCSS

Looping through two @each lists in SCSS

What you need to do is create a loop inside the first loop (I've simplified a bit so it's easier to see):

@mixin style-matrix($colors, $styles) {
@each $s in $styles {
@each $c in $colors {
.#{$s} .#{$c} {
background:image-url("xsppsfhair-#{$s}-#{$c}.svg");
}
}
}
}

$colors: blonde, brunette, auburn;
$styles: beehive, pixie, bob;
@include style-matrix($colors, $styles);

You get this output:

.beehive .blonde {
background: image-url("xsppsfhair-beehive-blonde.svg");
}

.beehive .brunette {
background: image-url("xsppsfhair-beehive-brunette.svg");
}

.beehive .auburn {
background: image-url("xsppsfhair-beehive-auburn.svg");
}

.pixie .blonde {
background: image-url("xsppsfhair-pixie-blonde.svg");
}

.pixie .brunette {
background: image-url("xsppsfhair-pixie-brunette.svg");
}

.pixie .auburn {
background: image-url("xsppsfhair-pixie-auburn.svg");
}

.bob .blonde {
background: image-url("xsppsfhair-bob-blonde.svg");
}

.bob .brunette {
background: image-url("xsppsfhair-bob-brunette.svg");
}

.bob .auburn {
background: image-url("xsppsfhair-bob-auburn.svg");
}

sass @each loop with multiple lists

Based on my understanding, I think @each is not the correct option for you as you don't have the key and value pair as one item. Below is what the documentation says about @each: (emphasis is mine)

The @each directive can also use multiple variables, as in @each $var1, $var2, ... in <list>. If <list> is a list of lists, each element of the sub-lists is assigned to the respective variable.

As you can see from the above statement, in your case the $ids would be treated as one list and the $colors would be treated as another. It means that

  • 1st iteration $id is 21, $color is 33 and 73 not assigned
  • 2nd iteration $id is #fff, $color is #000 and #333 is not assigned.

It might be better for you to use the @for loop like in the below snippet:

$ids: 21, 33, 73;
$colors: #fff, #000, #333;

@for $i from 1 through length($ids) {
$id: nth($ids, $i);
$color: nth($colors, $i);
.category--#{$id},
.post--#{$id} {
color: #{$color};
}
}

SCSS - Loop a list starting at key 2

You can skip the first entry using map-remove (note I added * 1px) to get unit values :)

This will not mutate the $breakpoints map

@each $key, $value in map-remove($breakpoints, all) {
@media (max-width: $value * 1px){
// dummy content printing out the breakpoint
body::before { content: '#{$key}' }
}
}

SASS/SCSS @each multiple arrays

Here's a DEMO

If you need to keep your values separate, in 2 lists, then you can...

// loop over $buttonNames
@each $buttonName in $buttonNames {
// Find the current index of $buttonNames...
$index: index($buttonNames, $buttonName);
// ... to pull the right from $buttonColors
@include underlineButton('btn', $buttonName, 3, nth($buttonColors, $index));
}

However, using a map is a little easier.

$buttons: (
'black': black,
'primary': blue,
'red': red,
'green': green
);

@each $buttonName, $color in $buttons {
@include underlineButton('btn', $buttonName, 3, $color)
}

SCSS @each loop with two variable sets?

Rather than use nested loops, what you want to do is use the zip function to zip your lists together. The zip function creates a list of lists where the first, second, etc. element of each list is paired up together:

$first: first_1 first_2;
$second: second_1 second_2;
@each $k, $v in zip($first, $second) {
.example-class[data-reactid$='#{$k}'] {
&:before {
content: '#{$v}';
}
}
}

Output:

.example-class[data-reactid$='first_1']:before {
content: "second_1";
}

.example-class[data-reactid$='first_2']:before {
content: "second_2";
}

Loop two-level nested lists in SCSS to create a dynamic @font-face

For those who might help: I ended up using the following approach:

@each $font-type, $font-variants in $fonts {
@each $properties, $font-variant in $font-variants {
@font-face {
@each $property, $value in $font-variant {
@if $property != 'src' {
font-#{$property}: $value;
} @else {
#{$property}: $value format('woff2');
}
}
}
}
}

It outputs the following:

Sample Image

How to loop through two Sass maps?

If both maps has same structure then you should use a single map only, but if you want to use both then use map-merge() like,

$map-one: (
name1: value1,
name2: value2,
name3: value3,
name4: value4,
);

$map-two: (
name5: value5,
name6: value6,
);

$merged: map-merge($map-one, $map-two);
@each $name, $value in $merged {
.#{$name} {
content: $value;
}
}

SCSS: How to combine @for with @each?

Problem is that you have a first loop with @for looping through all the values of $statistics and then @each doing the same which results in repeated values. This should be done with a single loop. I can think of two ways of achieving what you want:

.row {
@for $i from 1 through length($statistics) {
$variable: nth($statistics, $i);

.col:nth-child(#{$i}) {
color: var(--#{$variable});
}
}
}

or

.row {
@each $variable in $statistics {
$i: index($statistics, $variable);
.col:nth-child(#{$i}) {
color: var(--#{$variable});
}
}
}

In the case of the variable defined as:

$statistics: (
"header": ("first", "second", "third")
);

You can use map-get to obtain the variables. Something like:

$header: map-get($statistics, "header");

@each $variable in $header {
$i: index($header, $variable);

.col:nth-child(#{$i}) {
color: var(--#{$variable});
}
}

This is the same as before but looping with $header instead of $statistics

SASS | @for and @each loop printing values from a list issues

Instead of introducing an inner @for loop that will inevitably render two properties in each ruleset, try using a single loop:

@for $i from 1 through length($btn-class) {
#{nth($btn-class, $i)} {
background-color: nth($btn-color, $i)
}
}

In the long run however, I would recommend using maps instead. This way you have a clear association between class names and colors which will avoid potential mistakes in larger lists of elements:

$buttons: (
btn-default: $btn-default,
btn-alert: $btn-alert
);

@each $class, $color in $buttons {
.#{$class} {
background-color: $color;
}
}


Related Topics



Leave a reply



Submit