Get variable name from variable value in SASS/SCSS - css

I'd like to access variable within an #each loop using defined value like in the following example:
$car:true;
$people:false;
$job:false;
#mixin options($someval){
#each $prefix in car,people,job{
#if $#{$prefix} == true{
//some CSS...
}
}
}
Variable would be a sort of "semaphores" that define whether print or not Css rules.
My big doubt is how can I check over dynamically defined variables name ?
I've tried with $#{$prefix} but it doesn't work.
EDIT ---------------------------
I'd like to obtain this CSS
car-something: 34px;
Where the word "car" is taken from $prefix and in the first round of #each loop $#{$prefix} becomes $car
The problem is on $#{$prefix} ... it doesn't work :P i get an error

This is an old question but since it has no valid answer, here it is
You need to pass a map to #each
$car:true;
$people:false;
$job:false;
#mixin options($someval){
#each $key, $val in (car: $car, people: $people, job: $job) {
#if $val == true{
#{$key}-something: $someval
}
}
}
test {
#include options(34px)
}

Instead of trying to interpolate a variable name, pass a list to the mixin.
$car: true;
$people: false;
$job: false;
$thing-list: $car, $people, $job;
#mixin thingamajig($thing-list) {
#each $thing in $thing-list {
#if $thing {
// Some CSS
}
}
}

Related

Can you have an array inside a sass object value?

I'm trying to have an array inside an object's value.
$background-things: (
'a': ['100vh', 'transparent', 'column'],
'higher': ['70vh', '#000', 'column'],
'lower': ['30vh', '#fff', 'row'],
);
and then later call them like this:
#each $name, $value in $background-things {
#background {
&-#{$name}: {
#include column($height:$value[0], $background-color:$value[1], $flex-direction:$value[2]);
}
}
}
This doesn't work. Is there any way to do this? On a side note, does the value $name work, because in the object's property I put '&-a'.
It is possible. #each part needs some modification:
&-#{$name}: should convert to &-#{$name}.
Access to list (array) items is possible with nth function; for example nth($value, 1).
lists indexes start from 1.
Also '100vh' doesn't need '.
More information about lists: https://sass-lang.com/documentation/modules/list
#each $name, $value in $background-things {
#background {
&-#{$name} {
#include column($height:nth($value, 1), $background-color:nth($value, 2), $flex-direction:nth($value, 3));
}
}
}

SASS mixin outputs function in compiled CSS

My compiled CSS when viewed has a SASS function in it that was never compiled. This is presumably caused by the mixin I'm using to auto generate classes. I have no idea how to fix it.
SASS code:
$rsColors: (
main: (
base: #333030,
lighter:#827a7a,
light:#5a5555,
dark:#0c0b0b,
darker:#000000,
red: #211010,
accent:#999595,
border: #666666
),
link: (
base: #c42727,
lighter:#eb9999,
light:#de5959,
dark:#841a1a,
darker:#440e0e,
hover:#841a1a,
bg:rgba(80, 80, 80, 0.8),
bgHover: #cccccc
)
}
#mixin modifiers($map, $attribute, $prefix: '-', $hover: 'false', $separator: '-',$base: 'base', $type: 'darken', $perc: '15%') {
#each $key, $value in $map {
&#{if($key != $base, #{$prefix}#{$key}, '')} {
#if type-of($value) == 'map' {
#include modifiers($value, $attribute, $separator, $hover);
}
#else {
#{$attribute}: $value;
#if $hover == 'true' {
&:hover {
$function: get-function($type);
#{$attribute}: call($function,$value,$perc);
}
}
}
}
}
}
.rsBg {
#include modifiers($rsColors, 'background', $hover: 'true');
}
Compiled CSS (as viewed from style editor in Firefox inspector):
...
.rsBg-yellow-700 {
background: #b7791f;
}
.rsBg-yellow-700:hover {
background: darken(#b7791f, 15%);
}
...
How can I fix the compiled CSS so it's rendered correctly? I figure the mixin is to blame since it's outputting what I'm telling it to. Why it's not compiling before being output to CSS?
Expected Output:
...
.rsBg-yellow-700 {
background: #b7791f;
}
.rsBg-yellow-700:hover {
background: #915300; //assuming 15% darken
}
...
**Edit**
After some testing I have found I needed to add the ```get-function()``` method to get ```call()``` to work. However, no matter what I try I can not get the ```$perc``` variable in such a way as to not throw a "not a number" error. I can hard code percentages and it will compile without errors.. but I'd rather not have to do that.
The problem actually comes from the way you call the function and not the mixin. Instead of:
#{$attribute}: unquote(#{$type}($value, #{unquote($perc)}));
You should use the built-in function call() as below:
#{$attribute}: call($type, $value, $perc);
You also need to remove the quotation marks for the parameter $perc or you will get an error such as: $amount: "15%" is not a number for 'darken'. I tried to remove them with unquote() but it doesn't seem to work.
The answer to this issue was the use of '' in the arguments. Specifically the $lightness variable (which was changed from the #perc variable). Once I removed the quotes and just let it hang there, everything compiled and worked fine.
I removed the $type variable and changed the function to scale_color as it seemed to fit better with what I wanted. I should probably change the argument variable to a different name so not to be confused with the scale_color() argument. A task for a different day though.
PLEASE NOTE: I am accepting #Arkellys answer because it set me on the right path to this answer, and I feel really weird about accepting my own answer. I just added this answer so if another comes along it might help. Thank you #Arkellys for your help!
The final mixin
#mixin modifiers($map, $attribute, $prefix: '-', $hover: 'false', $separator: '-',$base: 'base', $lightness: -15%) {
#each $key, $color in $map {
&#{if($key != $base, #{$prefix}#{$key}, '')} {
#if type-of($color) == 'map' {
#include modifiers($color, $attribute, $separator, $hover);
}
#else {
#{$attribute}: $color;
#if $hover == 'true' {
&:hover {
#{$attribute}: scale_color($color,$lightness: $lightness);
}
}
}
}
}
}
.rsBg {
#include modifiers($rsColors, 'background', $hover: 'true', $lightness: -20%);
}

Scalable, global variable assignment #mixin for Sass

I thought that I had already solved this, but the code is not compiling in the way that I intend.
Here is my current code:
$prefix: 'foo';
#mixin var-assign($var, $val) {
$var: $val !global;
};
// will output .foo-selector
.#{$prefix}-selector {
/* ... */
}
#include var-assign($prefix, 'bar');
// should output .bar-selector
.#{$prefix}-selector {
/* ... */
}
The code above prints .foo-selector twice. Where am I going wrong that I am not printing one instance of .foo-selector ad one instance of .bar-selector?
You need to changes in your mixin variable, Try using
#mixin var-assign($prefix, $val) {
$prefix: $val !global;
};
Working example here:

SASS mixin is included even though class doesn't exist

I created two mixins which assign different values to the same variable that I want to use later in the header background url.
Depending on the html class variable $image-name should be different since I include different mixins but it always has a "second-img" value even though class .second doesn't exist in my html.
Please let me know if there is a better way to do this.
Thanks!
#mixin first-image($image) {
$image-name: $image !global;
}
#mixin second-image($image) {
$image-name: $image !global;
}
html.first {
#include first-image("first-img");
}
html.second {
#include second-image("second-img");
}
header {
background-image: url(../images/#{$image-name}-banner.jpg);
}
Your code when executed looks like this:
html.second {
second-img {
$image-name: second-img !global;
}
}
Your mixing is pulling in the value of $image that you defined during the #include as they have the same variable names.
#mixin second-image($image) {
$image-name: $image !global;
}
Change the variable name to something else and it won't display the same:
#mixin second-image($image) {
$image-name: $thingy !global;
}

sass how to instantiate an empty variable to be set by #if

I think the code speaks for itself so this is what I have:
#mixin btnNoBackgr30($divName, $iconName, $xtypeYesOrNo ){
$xtypeBtn:nil;
#if xtypeYesOrNo == 'yes'{
$xtypeBtn:x-button-#{$divName};
}
#if xtypeYesOrNo == 'no'{
$xtypeBtn:#{$divName};
}
.#{$xtypeBtn}{
properties:values;
}
all I get in css is this
.nil{
properties:values;
}
How can instantiate the variable outside the #if?
If I do it inside the #if ofc it wont be detected outside the scope like normal programming and marked ans 'undefined'
Please help. false do the same and Null give me errors
give $xtypeBtn some random default value as it will be reset anyway? If $xtypeYesOrNo can be undefined, give it a default value too?
#mixin btnNoBackgr30($divName, $iconName, $xtypeYesOrNo:default) {
$xtypeBtn:default;
#if $xtypeYesOrNo != default {
// do whatever
}
#if xtypeYesOrNo == yes {
$xtypeBtn: x-button-#{$divName};
}
#if xtypeYesOrNo == no {
$xtypeBtn: #{$divName};
}
.#{$xtypeBtn} {
properties: values;
}
}

Resources