I want to use a SCSS loop as below:
#each $var in dark, purple, green, cyan, silver, white {
.text-#{$var} {
color: nth($color-, $var);
}
.btn-#{$var} {
background-color: nth($color-, $var);
}
}
in order to use the following variables:
$color-dark: #0D0E1E;
$color-purple: #333366;
$color-green: #33cc99;
$color-cyan: #00cccc;
$color-silver: #ccc;
$color-white: #fff;
but it is not working.
$color-#{$var} was not working as well. Can I do this?
nth gets an item in a list. The first argument is the list, the 2nd is an index in the list. Also SASS thinks anything with a $ is a variable, so $color- is a variable. You haven't defined $color- as a variable, and that's not your intended use.
DOCS.
But you can get your desired result with a map...
DEMO
$color-dark: #0D0E1E;
$color-purple: #333366;
$color-green: #33cc99;
$color-cyan: #00cccc;
$color-silver: #ccc;
$color-white: #fff;
$colors: (
dark: $color-dark,
purple: $color-purple,
green: $color-green,
cyan: $color-cyan,
silver: $color-silver,
white: $color-white
);
#each $name, $val in $colors {
.text-#{$name} {
color: $val;
}
.btn-#{$name} {
background-color: $val;
}
}
Related
SCSS
$colors: (
primary: red,
secondary: blue,
accent: #ddd,
) !default;
$colors: (
primary: green,
secondary: purple,
black: #000,
white: #fff,
);
#each $color, $value in $colors {
.alert-#{$color} {
color: $value;
}
}
Result
.alert-primary {
color: green;
}
.alert-secondary {
color: purple;
}
.alert-black {
color: #000;
}
.alert-white {
color: #fff;
}
I wanted to create a SASS framework something like bootstrap. Wanted to override theme colors. How can i merge these maps to get something like this? I want a simple solution.
Expected result
.alert-accent {
color: #ddd;
}
.alert-primary {
color: green;
}
.alert-secondary {
color: purple;
}
.alert-black {
color: #000;
}
.alert-white {
color: #fff;
}
You can use map-merge:
$colors: map-merge($colors, (
primary: green,
secondary: purple,
black: #000,
white: #fff
));
From the documentation, this function:
Returns a new map with all the keys and values from both $map1 and $map2.
This can also be used to add a new value or overrwrite a value in $map1, by passing a single key/value pair as $map2.
If both $map1 and $map2 have the same key, $map2’s value takes precedence.
I need to create dynamic classes for which I am creating a scss code to create the classes for all the possible values. Below is my code:-
$colors: (
"black": "0,0,0",
"white": "255,255,255",
"red" : "255,0,0"
);
$opacity:9;
#for $i from 0 through $opacity {
$j:$i/10;
#each $color, $rgb in $colors {
$rgba: "#{$rgb},#{$j}";
.background-#{$color}-#{$i} {
background: #{$rgba};
}
}
}
I want it to give out put as :-
.background-black-0 {
background: rgba(0,0,0,0);
}
.background-white-0 {
background: rgba(255,255,255,0);
}
.background-red-0 {
background: rgba(255,0,0,0);
}
.background-black-1 {
background: rgba(0,0,0,0.1);
}
.background-white-1 {
background: rgba(255,255,255,0.1);
}
.background-red-1 {
background: rgba(255,0,0,0.1);
}
struggling with the interpolation for rgba(). Otherwise its getting the exact values I want. If you check my code in https://www.sassmeister.com/ you will see it.
You could use directly your colors as rgb color in your map and then add opacity in your #for loop:
$colors: (
"black": rgb(0,0,0),
"white": rgb(255,255,255),
"red": rgb(255,0,0)
);
$opacity:9;
#for $i from 0 through $opacity {
$j:$i/10;
#each $color, $rgb in $colors {
.background-#{$color}-#{$i} {
background: rgba($rgb, $j);
}
}
}
developing in scss
I have the two variable lists:
$ids: 21, 33, 73;
$colors: #fff, #000, #333;
and the following #each loop.
#each $id, $color in ($ids, $colors) {
.category--#{$id},
.post--#{$id} {
color: #{$color};
}
}
I want to display the following
.category--21,
.post--21 {
color: #fff
}
.category--33,
.post--33 {
color: #000
}
.category--73,
.post--73 {
color: #333
}
But I'm getting this instead
.category--21,
.post--21 {
color: 33;
}
.category--#fff,
.post--#fff {
color: #000;
}
Unsure of my structure. Obviously I have much longer variables lists (just added 3 to each one for demo purposes).
Any constructive feedback welcome. Thanks
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};
}
}
Hi you misuse it :D #each is iterate list by list see below
$pair: (21, #fff), (33, #000), (73, #333);
#each $id, $color in $pair {
.category-#{$id},
.post-#{$id} {
color: #{$color};
height: 20px;
}
}
doc reference: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#each-multi-assign
I have a list in SASS, and I'm trying to access on of the items by using bracket notation:
$collection[1];
but that gives me an error.
Is there any other way to do this?
Why do I want to do this?
I have a list of colors that have to be set on different elements according to a colors assigned to them by the server. The markup has numbered classes (color-0, color-1, etc.). Here's the CSS I'm aiming for:
.color-0 { color: red }
.color-1 { color: orange }
.color-2 { color: green }
.color-3 { color: blue }
/* many more, with more complex colors... */
Instead of writing it all by hand, I figured I could use a SASS collection with a loop:
$color-collection: ('red', 'orange', 'green', 'blue');
$color-count: length($color-collection);
#for $i from 0 to $color-count {
.color-#{$i} {
color: $color-collection[ $i ];
}
}
but this just gives me the following error:
Syntax error: Invalid CSS after "...color-collection": expected ";", was "[ $i ];"
How can I accomplish this?
$color-collection: ('red', 'orange', 'green', 'blue');
#for $i from 0 to length($color-collection) {
.color-#{$i} {
color: unquote(nth($color-collection, $i+1));
}
}
Use nth(), also unquote() if you want to pass quoted strings.
Though, I personally wouldn't:
$color-collection: (red, rgba(50,50,80, .5), darken(green, 50%), rgba(blue, .5));
#for $i from 0 to length($color-collection) {
.color-#{$i} {
color: nth($color-collection, $i+1);
}
}
Because then you can pass any color object.
You can use #each rule instead of #for, which is more semantic, faster, and it makes the code shorter:
$color-collection: (red, orange, green, blue);
#each $color in $color-collection {
.color-#{$color} {
color: $color;
}
}
Or if you prefer you can use $color-collection list directly into the #each directive:
#each $color in red, orange, green, blue {
.color-#{$color} {
color: $color;
}
}
As #bookcasey says is preferable to use unquoted strings because then you can pass any color object or function
Sass reference for #each directive
just came across this and tested bookcasey's answer, which works well but I wanted to use the color name as the class instead; I found that this code works as I needed.
$colors: ( 'black', 'white', 'red', 'green', 'blue' );
#for $i from 0 to length($colors) {
$thisColor: unquote(nth($colors, $i+1));
.color-#{$thisColor} {
color: $thisColor;
}
}
using the #{...} allows you to use functions as well, so if you need to use an arbitrary name that may not be used directly in the rules you could use
#for $i from 0 to length($colors) {
.color-#{unquote(nth($colors, $i+1))} {
// some rules that don't actually use the var
// so there's no need to cache the var
}
}
output:
.color-black { color: black; }
.color-white { color: white; }
.color-red { color: red; }
// etc..
Hope this helps someone else!
I had similar problem and tried Alex Guerrero solution. Didn't work form me cause output was like .color-gray:{gray}; instead of .color-1:{gray};.So I modified it a bit and it looks like this:
$color-pallete: (gray, white, red, purple)
$i: 0
#each $color in $color-pallete
.color-#{$i}
color: $color
$i: $i + 1
Oh, ye. I use SASS, not SCSS.
I have a list in SASS, and I'm trying to access on of the items by using bracket notation:
$collection[1];
but that gives me an error.
Is there any other way to do this?
Why do I want to do this?
I have a list of colors that have to be set on different elements according to a colors assigned to them by the server. The markup has numbered classes (color-0, color-1, etc.). Here's the CSS I'm aiming for:
.color-0 { color: red }
.color-1 { color: orange }
.color-2 { color: green }
.color-3 { color: blue }
/* many more, with more complex colors... */
Instead of writing it all by hand, I figured I could use a SASS collection with a loop:
$color-collection: ('red', 'orange', 'green', 'blue');
$color-count: length($color-collection);
#for $i from 0 to $color-count {
.color-#{$i} {
color: $color-collection[ $i ];
}
}
but this just gives me the following error:
Syntax error: Invalid CSS after "...color-collection": expected ";", was "[ $i ];"
How can I accomplish this?
$color-collection: ('red', 'orange', 'green', 'blue');
#for $i from 0 to length($color-collection) {
.color-#{$i} {
color: unquote(nth($color-collection, $i+1));
}
}
Use nth(), also unquote() if you want to pass quoted strings.
Though, I personally wouldn't:
$color-collection: (red, rgba(50,50,80, .5), darken(green, 50%), rgba(blue, .5));
#for $i from 0 to length($color-collection) {
.color-#{$i} {
color: nth($color-collection, $i+1);
}
}
Because then you can pass any color object.
You can use #each rule instead of #for, which is more semantic, faster, and it makes the code shorter:
$color-collection: (red, orange, green, blue);
#each $color in $color-collection {
.color-#{$color} {
color: $color;
}
}
Or if you prefer you can use $color-collection list directly into the #each directive:
#each $color in red, orange, green, blue {
.color-#{$color} {
color: $color;
}
}
As #bookcasey says is preferable to use unquoted strings because then you can pass any color object or function
Sass reference for #each directive
just came across this and tested bookcasey's answer, which works well but I wanted to use the color name as the class instead; I found that this code works as I needed.
$colors: ( 'black', 'white', 'red', 'green', 'blue' );
#for $i from 0 to length($colors) {
$thisColor: unquote(nth($colors, $i+1));
.color-#{$thisColor} {
color: $thisColor;
}
}
using the #{...} allows you to use functions as well, so if you need to use an arbitrary name that may not be used directly in the rules you could use
#for $i from 0 to length($colors) {
.color-#{unquote(nth($colors, $i+1))} {
// some rules that don't actually use the var
// so there's no need to cache the var
}
}
output:
.color-black { color: black; }
.color-white { color: white; }
.color-red { color: red; }
// etc..
Hope this helps someone else!
I had similar problem and tried Alex Guerrero solution. Didn't work form me cause output was like .color-gray:{gray}; instead of .color-1:{gray};.So I modified it a bit and it looks like this:
$color-pallete: (gray, white, red, purple)
$i: 0
#each $color in $color-pallete
.color-#{$i}
color: $color
$i: $i + 1
Oh, ye. I use SASS, not SCSS.