I have the following SASS variables:
$msg: #669bdf;
$msg-h: #548ed8;
$msg-a: #3873be;
$suc: #1cBB9c;
$suc-h: #10b091;
$suc-a: #10947a;
How do I concatenate $ with interpolation without errors
#each $color in $color-list {
.#{$color} {
background-color: #{$#{$color}};
&:hover {
background-color: #{$#{$color}}-h;
}
&:active {
background-color: #{$#{$color}}-a;
}
}
}
I think the following may work for you:
$color-list: (
msg: (
base: #669bdf,
hover: #548ed8,
active: #3873be
),
suc: (
base: #1cBB9c,
hover: #10b091,
active: #10947a
)
);
#each $name, $colors in $color-list {
.#{$name} {
background-color: map-get($colors, base);
&:hover {
background-color: map-get($colors, hover);
}
&:active {
background-color: map-get($colors, active);
}
}
}
Edit: You can't concatenate variables the way you want to, so that's why I came up with this solution.
I was wondering whether there is a certain way to use variables that affect the style in SCSS.
I'm looking for something like:
var x = 1
.class1 {
if (x==1) {
background-color: red;
} else {
background-color: blue;
}
}
.class2 {
if (x==1) {
background-color: blue;
} else {
background-color: red;
}
}
You can use #if and #else
$x:1;
.class1 {
#if $x == 1 {
background-color: red;
} #else {
background-color: blue;
}
}
.class2 {
#if $x == 1 {
background-color: blue;
} #else {
background-color: red;
}
}
I'm trying to create a color weight mixin. The result would be something like Google Material's color weights ( https://material.io/guidelines/style/color.html#color-color-palette ).
I'm hoping for a function where I could pass the base color and it would lighten / darken for each weight creating variables and classes for each weight.
Take the following manually done weights:
$color-blue: #1483ff;
$color-blue-100: lighten($color-blue, 30%);
$color-blue-200: lighten($color-blue, 20%);
$color-blue-400: lighten($color-blue, 10%);
$color-blue-500: $color-blue;
$color-blue-600: darken($color-blue, 10%);
$color-blue-700: darken($color-blue, 20%);
$color-blue-800: darken($color-blue, 30%);
$color-blue-900: darken($color-blue, 40%);
I was experimenting with something like this:
$colors: $color-blue-100, $color-blue-200, $color-blue-300;
#for $c from 1 through length($colors)-1 {
.bg-blue-#{$i} {
background: $c;
}
}
but that doesn't work and I still have to manually define the variables.
I took the approach of iterating over a predefined "palette" where the weights and percentages are static as well for colors. All you would have to do going forward is to add/change the colors defined.
$colors : (
"blue" : #1483ff,
"green" : #4CAF50,
"yellow" : #FFEB3B,
);
$palette : (
100 : 40%,
200 : 30%,
300 : 20%,
400 : 10%,
500 : 0,
600 : 10%,
700 : 20%,
800 : 30%,
900 : 40%
);
#each $name, $hex in $colors {
#each $weight, $percentage in $palette {
#if $weight < 500 {
.bg-#{"" + $name}-#{$weight} {
background-color: lighten($hex, $percentage);
}
} #else if $weight > 500 {
.bg-#{"" + $name}-#{$weight} {
background-color: darken($hex, $percentage);
}
} #else {
.bg-#{"" + $name}-#{$weight} {
background-color: $hex;
}
}
}
}
Which compiles to
.bg-blue-100 {
background-color: #e0efff;
}
.bg-blue-200 {
background-color: #add4ff;
}
.bg-blue-300 {
background-color: #7ab9ff;
}
.bg-blue-400 {
background-color: #479eff;
}
.bg-blue-500 {
background-color: #1483ff;
}
.bg-blue-600 {
background-color: #006ae0;
}
.bg-blue-700 {
background-color: #0052ad;
}
.bg-blue-800 {
background-color: #003a7a;
}
.bg-blue-900 {
background-color: #002247;
}
.bg-green-100 {
background-color: #d9eeda;
}
.bg-green-200 {
background-color: #b5dfb7;
}
.bg-green-300 {
background-color: #92cf94;
}
.bg-green-400 {
background-color: #6ec071;
}
.bg-green-500 {
background-color: #4CAF50;
}
.bg-green-600 {
background-color: #3d8b40;
}
.bg-green-700 {
background-color: #2d682f;
}
.bg-green-800 {
background-color: #1e441f;
}
.bg-green-900 {
background-color: #0e210f;
}
.bg-yellow-100 {
background-color: white;
}
.bg-yellow-200 {
background-color: #fffbd4;
}
.bg-yellow-300 {
background-color: #fff5a1;
}
.bg-yellow-400 {
background-color: #fff06e;
}
.bg-yellow-500 {
background-color: #FFEB3B;
}
.bg-yellow-600 {
background-color: #ffe608;
}
.bg-yellow-700 {
background-color: #d4be00;
}
.bg-yellow-800 {
background-color: #a19100;
}
.bg-yellow-900 {
background-color: #6e6300;
}
This should do it and no variables to define. You can see the output on sassmeister.
#mixin color-weight ($class, $base-color, $weight: 4) {
$bg-color: null;
#for $i from 1 through 8 {
#if $i < 4 {
$weight: $weight - 1;
$bg-color: lighten($base-color, $weight * 10%);
} #else if $i == 4 {
$weight: 0;
$bg-color: $base-color;
} #else {
$weight: $weight + 1;
$bg-color: darken($base-color, $weight * 10%);
}
.#{$class}-#{$i} { background-color: $bg-color; }
}
}
#include color-weight(bg-blue, #1483ff);
#include color-weight(mad, red);
I want to adapt padding like this.
it is possible to solve using sass mixin or another way
.list {
.item {
.text-box {
padding-left: 10px;
}
}
.list {
.item {
.text-box {
padding-left: 20px;
}
}
.list {
.item {
.text-box {
padding-left: 30px;
}
}
.list {
.item {
.text-box {
padding-left: 40px;
}
}
}
}
}
}
What about a loop with #for directive?
$list: ".list";
#for $i from 0 through 3 {
#{$list} {
.item {
.text-box {
padding-left: (10px + $i*10px);
}
}
}
$list: append($list, ".list");
}
I write CSS in BEM style and have this code:
.nav {
&__list {
&__item {
}
}
&__link {
&--active {
}
}
}
How do I get .nav .nav__link--active and .nav__link.nav__link--active from code above? How can I enhance the specificity by this method?
There is no magic method for this. Store the desired selector as a variable and nest like normal.
.nav {
$sel: &;
&__list {
&__item {
color: red;
#{$sel} & {
border: 1px solid;
}
}
}
&__link {
&--active {
color: blue;
#{$sel} & {
border: 1px dashed;
}
}
}
}