Sass Loop Through Array and Present Variable

Sass Loop through array and present variable

I think that you have to got this simpler. I would create a list to manage colors. This way you are properly creating variables and avoid repeating code.

$colors-list:(
default: 'chalk',
blush: 'blush',
brick: 'brick',
pink: 'pink',
slate: 'slate'
);

If you want a more descriptive and semantic way to separate the name of the color to its functionality, you can do a nested list of variables of colors like this:

  $chalk: 'chalk';
$blush: 'blush';
$brick: 'brick';
$pink: 'pink';
$slate: 'slate';

$colors-list:(
default: $chalk,
blush: $blush,
brick: $brick,
pink: $pink,
slate: $slate
);

The problem in your code is that you are trying to reference variables by interpolation #{} and variable name interpolation is not supported by SASS. Variables are called by its whole name. You also are repeating colors lists.

Why not:

@each $key,$val in $colors-list{
.speech-bubble--#{$key} {
background-color: #{$val};
}
}

SCSS / SASS : How to create variables inside an each loop

As Flying mentioned in the comments Sass does not support dynamic variables creation.
I think I would use a function to return the CSS variable if found in the $colors map

$colors : (
"pink" : #E20071,
"blue" : #00A3DA,
"gray" : #939394,
"darkGray" : #939394,
"yellow" : #FEA347,
"green" : #4CA66B,
"white" : #FFFFFF,
"black" : #1B1B1B,
);

:root{
@each $key, $value in $colors {
--#{$key} : #{$value};
}
}

@function color($name){
@if not map-get($colors, $name+''){
@error "Color `#{$name}` not found in map $colors";
}
@return var(--#{unquote($name)});
}

.class-name {
color: color(pink); // var(--pink);
color: color(nope); // throws error: "Color `nope` not found in map $colors"
}

// note! we stringify $name (the +'' part) to ensure Sass does not interpret
// it as a color – e.g. pink represents the hex value #ffc0cb

scss - an elegant way to loop through variables

What about something like this?

$variants: (
blue: (
main: #2E6FFF,
light: #E8F1FB
),
purple: (
main: #a718f1,
light: #F4F2FF
),
...
);

.grid-box--resource {
@each $variant, $colors in $variants {
$main: map-get($colors, main);
$light: map-get($colors, light);

&.--variant-#{$variant} {
.btn {
background-color: $main;
color: #fff;

&:hover {
background-color: rgba($main, 0.8);
}
}

.bg-color {
background-color: $light;
}

.resource-card__icon i {
color: $main;
}
}
}
}

And you can use HEX color codes in rgba() directly.

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};
}
}

Loop array sass and create css

The first loop @each $current-position in $positions is causing your problem. You can remove it and achieve what you want with a map:

$short-paddings: (
top: 'pt',
left: 'pl',
bottom: 'pb',
right: 'pr'
);

@for $i from 1 through 2 {
@each $position, $prefix in $short-paddings {
.#{$prefix}-#{$i} {
padding-#{$position}: #{$i}px !important;
}
}
}

SASS Maps documentation

SASS loop within a loop variable

It may be better to use a multi-map structure:

$event_list: (
'summit': (
key1: #000,
key2: #fff
),
'awards': (
content-marketing: #F47521,
digiday: #FFDD00,
publishing: #89C63F,
signal: #33AADB,
video: $pink
)
);

The loop will be about the same:

// Note the added $map variable.
@each $event_type, $map in $event_list {

@each $event, $color in $map {

&.#{$event_type}-#{$event} {
section h2, h3 {
color: #{$color};
border-color: #{$color};
}

// More CSS
}
}
}

SassMeister Demo

@each-loop using map-get( )

You get that error 'cause you are not looping real maps (http://sass-lang.com/documentation/file.SASS_REFERENCE.html#maps).

You could use a nested map to resolve your problem. Something like this:

$names: (
layout-1: (
name: "name-1",
filename: "name-1.jpg",
color: blue
),

layout-2: (
name: "name-2",
filename: "name-2.jpg",
color: red
)
);

@each $key, $value in $names {
.#{map-get($value, name)} {
background-image: url("#{map-get($value, filename)}");
color: map-get($value, color);
}
}

@each loop with index

First of all, the @each function is not from Compass, but from Sass.


To answer your question, this cannot be done with an each loop, but it is easy to convert this into a @for loop, which can do this:

@for $i from 1 through length($refcolors) {
$c: nth($refcolors, $i);

// ... do something fancy with $c
}

Loop in Sass @for how to use $#{value}#{$i} correctly?

You can set a variable of $menu-icon-items:"\f007","\f07c","\f1fa"; and loop through using its length, see example here:

HTML

<div class="menu-item1">1</div>
<div class="menu-item2">2</div>
<div class="menu-item3">3</div>

SCSS

$menu-icon-items:"\f007","\f07c","\f1fa";
@for $i from 1 through length($menu-icon-items) {
.menu-item#{$i}{
&:before {
content:nth($menu-icon-items,$i);
}
}
}


Related Topics



Leave a reply



Submit