sass $ concatenate with interpolation - sass

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.

Related

Sass variable not working in for

I have a problem converting a string to a variable, because it generates an error
I have tried in several ways to convert this variable into a line, in order to obtain the colors in the classes
c-gray + $i
SASS
$c-gray1: #666;
$c-gray2: #979797;
$c-gray3: #4c4c4c;
$c-gray4: #b9c6d1;
$c-gray5: #f7f8f9;
#for $i from 1 through 5 {
$colorsGrays: c-gray + $i;
$count: 1;
#each $color in $colorsGrays {
.gBgcGray#{$i} {
background-color: $color;
}
.gCGray#{$i} {
color: $color;
}
.g-bc--gray#{$i} {
border-color: $color;
}
$count: $count + 1;
}
}
OUTPUT:
.gBgcGray1 {
background-color: c-gray1;
}
.gCGray1 {
color: c-gray1;
}
.g-bc--gray1 {
border-color: c-gray1;
}
.gBgcGray2 {
background-color: c-gray2;
}
.gCGray2 {
color: c-gray2;
}
.g-bc--gray2 {
border-color: c-gray2;
}
.gBgcGray3 {
background-color: c-gray3;
}
.gCGray3 {
color: c-gray3;
}
.g-bc--gray3 {
border-color: c-gray3;
}
.gBgcGray4 {
background-color: c-gray4;
}
.gCGray4 {
color: c-gray4;
}
.g-bc--gray4 {
border-color: c-gray4;
}
.gBgcGray5 {
background-color: c-gray5;
}
.gCGray5 {
color: c-gray5;
}
.g-bc--gray5 {
border-color: c-gray5;
}
TEST: https://sass.js.org/
There is some way to generate a code with the correct one to get the values in the SASS and the OUTPUT
Sass can't resolve variables in this way, but you can use either list or map and resolve colors:
Using list:
$c-gray: #666 #979797 #4c4c4c #b9c6d1 #f7f8f9;
#for $i from 1 through 5 {
$colorsGrays: nth($c-gray, $i);
}
Using map:
$colors: (
c-gray1: #666,
c-gray2: #979797,
c-gray3: #4c4c4c,
c-gray4: #b9c6d1,
c-gray5: #f7f8f9,
);
#for $i from 1 through 5 {
$colorsGrays: map-get($colors, c-gray + $i);
}
Moreover in these cases you can use #each $colorGrays in $colors instead of #for

SaSS extend only properties

Is is possible in SaSS to only extend the css properties of a class, and avoid rendering a concatenated classname:
.class_A {
background-color: #f0f;
}
.class_B {
color:#555;
#extend class_A;
}
desired result:
.class_B {
color:#555;
background-color: #f0f;
}
If you still need .class_A then you can do this
%bg-color {
background-color: #f0f;
}
.class_A {
#extend %bg-color;
}
.class_B {
color:#555;
#extend %bg-color;
}
Output CSS:
.class_A, .class_B {
background-color: #f0f;
}
.class_B {
color: #555;
}
If you don't need .class_A just use a variable:
$bg-color: #f0f;
.class_B {
color:#555;
background-color: $bg-color;
}

Sass interpolate a variable name to string

We were provided a number of colors with specific hover-state colors associated:
$red: #cb333b;
$red-hover: #fe666e;
$brown: #544742;
$brown-hover: #877a75;
etc.
Since all the colors are formatted the same way, so I was hoping to write a mixin that takes the color's variable name, then concatenates -hover to the end. This is my first try:
#mixin button_colorizor($color) {
border-color: $color;
color: $color;
&:hover {
color: #{$color}-hover;
border-color: #{$color}-hover;
}
}
But what this does is output a color like this: #f1735f-hover. The same thing when I do this: color: #{$color+-hover};
You can create map of colors. And get color values by its names.
Demo on sassmeister.
$colors: (
red: #cb333b,
red-hover: #fe666e,
brown: #544742,
brown-hover: #877a75
);
#mixin button_colorizor($color) {
color: map-get($colors, $color);
border-color: map-get($colors, $color);
&:hover {
color: map-get($colors, $color + '-hover');
border-color: map-get($colors, $color + '-hover');
}
}
a {
#include button_colorizor(red);
}
span {
#include button_colorizor(brown);
}
This code is compiled to css:
a {
color: #cb333b;
border-color: #cb333b;
}
a:hover {
color: #fe666e;
border-color: #fe666e;
}
span {
color: #544742;
border-color: #544742;
}
span:hover {
color: #877a75;
border-color: #877a75;
}

Sass Mixin: Callback or Replace #content

I don't know if Sass is able to do this, but it doesn't hurt to ask.
The Problem
Basically I have three colors pattern that are repeated in multiple sections of application, like blue, green and orange. Sometimes what changes is the background-color, or the border-color of the component... Sometimes is the text color of a child element, etc.
What I thought?
1. Replace a string pattern inside a content.
.my-class {
#include colorize {
background-color: _COLOR_;
.button {
border-color: _COLOR_;
color: _COLOR_;
}
}
}
2. Providing a callback variable for #content.
// This is just a concept, IT DOESN'T WORK.
#mixin colorize {
$colors: blue, green, orange;
#each $colors in $color {
// ...
#content($color); // <-- The Magic?!
// ...
}
}
// Usage
#include colorize {
background-color: $color;
}
I tried to implement such solutions, but without success.
Instead of it...
See below my workaround to get it partially working:
#mixin colorize($properties) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
You can use this mixin that way:
.some-class {
#include colorize(background-color);
}
What will come output:
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
The problem? Well, I can't use it with child selectors.
Based on the above information, there is some magic solution for this case?
I think I figured out what you meant; it is a little (very) messy, but it should do what you want:
#mixin colorize($parentProperties,$childMaps) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:#{nth($colors, $index)} {
#each $property in $parentProperties {
#{$property}: #{nth($colors, $index)};
}
}
#each $mapped in $childMaps {
$elem: nth($mapped,1);
$properties: nth($mapped,2);
#{$elem}:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
}
It would turn out to be:
/* -------------- USAGE ------------------*/
.some-class {
#include colorize(
background-color,( //Parent properties
(button, background-color), //Child, (properties)
(span, (background-color,border-color)) //Child, (properties)
)
);
}
/* --------------- OUTPUT ----------------*/
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class button:nth-child(3n+1) {
background-color: blue;
}
.some-class span:nth-child(3n+1) {
background-color: blue;
border-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class button:nth-child(3n+2) {
background-color: green;
}
.some-class span:nth-child(3n+2) {
background-color: green;
border-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
.some-class button:nth-child(3n+3) {
background-color: orange;
}
.some-class span:nth-child(3n+3) {
background-color: orange;
border-color: orange;
}
Hope that that is what you are looking for :)

How to convert named color to HEX using SCSS?

I have a mixin with named colors:
#mixin color-classes-rendering {
$colors: (
rebeccapurple
);
#each $value in $colors {
.#{nw}-#{nth($value, 1)}#{" > span"} {
background-color: nth($value, 1);
}
}
}
Here is compiled CSS:
.nw-rebeccapurple > span {
background-color: rebeccapurple;
}
I don't know why, but "rebeccapurple" doesn't shown in Chrome at Android.
Is it possible to convert it to this one:
.nw-rebeccapurple > span {
background-color: #663399;
}
While Sass does provide functions to extract the individual R, G, and B values for any given color, it doesn't provide a convenient way to convert those to hexadecimal. It would be simpler for you to convert it to the rgb() format.
$color: rebeccapurple;
.foo {
color: #{'rgb(#{red($color)}, #{green($color)}, #{blue($color)})'};
}
Output:
.foo {
color: rgb(102, 51, 153);
}
See also: Why does Sass change the format of my colors?
I should also point out that what you've written so far would be better suited to a mapping:
$colors: (
'rebeccapurple': #639,
'black': #000
);
#each $name, $color in $colors {
.nw-#{$name} > span {
background-color: $color;
}
}
Output (compressed format):
.nw-rebeccapurple > span { background-color: #639; }
.nw-black > span { background-color: #000; }
My solution is to put the HEX value of each named color manually, like this:
#mixin color-classes-rendering {
$colors: (
rebeccapurple #663399,
black #000000
);
#each $value in $colors {
.#{nw}-#{nth($value, 1)}#{" > span"} {
background-color: nth($value, 2);
}
}
}

Resources