Switch value of a variable in SASS [duplicate] - css

This question already has answers here:
Dynamic Sass Variables
(3 answers)
Closed 8 years ago.
I'd like to do something like that in SASS:
$GREEN: #57da99;
$HEADER_PURPLE: #8585ff;
$BLUEISH: #4478ff;
$RED: #ff475d;
$RED2: #ff445e;
$currentColor:null;
body.page-about { $currentColor: $BLUEISH; }
body.page-browse { $currentColor: $GREEN; }
body.page-signup { $currentColor: $HEADER_PURPLE; }
body.page-login { $currentColor: $HEADER_PURPLE; }
body.page-contribute { $currentColor: $RED; }
I've no error, it's compiled with success. But when I check my page, the value of $currentColor is $RED even if I'm not in body.page-contribute.
So, I don't know if SASS doesn't handle it or if I made a big mistake.
Thanks.

You are declaring a Sass variable with a global scope, so each line is modifying the global var, like in JavaScript.
You can use #debug $currentColor; between you lines to see variable state.
You should probably use a mixin to prevent scope issue, or declare another variable with a local scope each time (try to just delete $currentColor:null;)

Remove the line $currentColor:null; - there is no need to instantiate variables in SASS outside their required scope.
$GREEN: #57da99;
$HEADER_PURPLE: #8585ff;
$BLUEISH: #4478ff;
$RED: #ff475d;
$RED2: #ff445e;
body.page-about { $currentColor: $BLUEISH; }
body.page-browse { $currentColor: $GREEN; }
body.page-signup { $currentColor: $HEADER_PURPLE; }
body.page-login { $currentColor: $HEADER_PURPLE; }
body.page-contribute { $currentColor: $RED; }

Related

Is there a way to define SASS variables in a" [data='value'] {}", or only regular CSS variables?

I want to export "$var" like variables defined as "--var" variables from a Scss file to be used in other files with some scss functions such as "darken()", but it says its not a color.
I'm coding a Vue/Vite website and implementing a theme-change button, that will write data at the HTML tag, and use it to define the theme.
<html lang="en" data-theme="dark"> ... </html>
The base.scss looks like this:
[data-theme="dark"] {
--primary: #c6c7df;
--secondary: #c95d63;
--text-light: #e2ebf5;
}
[data-theme="light"] {
--primary: #26298d;
--secondary: #c95d63;
--text-light: #2c3e50;
}
$primary: var(--primary);
$secondary: var(--secondary);
$text-light: var(--text-light);
I can use the "$var"-like variable at the end of the file, but when I use it inside a "darken($primary, 10%)" function, it gives the following error:
Error: $color: var(--primary) is not a color.
I know it's because I defined it as a CSS variable but if I define the variable inside the "[theme] {}" thing, it doesn't get innitialized and throws the error "Undefined variable"
I know it's a niche question, and I could use something like this, but I wish I could just export it as a scss variable.
Thank you very much.
Of course we cannot make a CSS variable lighten or darken. Think about, What will happen to the Name of CSS variable in the output?
So we have to define all CSS variables and assign desired colors, Before using them.
Solution
For this purpose, you can automatically create the list of CSS variables by #each and create a manual function by #function for easy use. This way gives us a standard css output and the best experience in Sass coding.
// Theme defines area:
$theme-colors:(
"primary": #940fe0,
"secondary": #e49f38,
"warning": #ffe600,
"info": #165ad6
);
$darken-percent: 20%;
$lighten-percent: 20%;
// Functions area:
:root {
#each $name, $color in $theme-colors {
$lighten: lighten($color, $lighten-percent);
$darken: darken($color, $darken-percent);
--color-#{$name}: #{$color};
--color-#{$name}-light: #{$lighten};
--color-#{$name}-dark: #{$darken};
}
}
#function cl($name, $color-tone) {
#if not map-get($theme-colors, $name+''){
#error "`#{$name}` is not defined in Colors Theme";
}
#if $color-tone == d {
#return var(--color-#{$name}-dark);
}
#if $color-tone == l {
#return var(--color-#{$name}-light);
}
#else{
#return var(--color-#{$name});
}
}
// Our custom function usage:
// Use 'b' to return Base color. Ex: cl(primary,b)
// Use 'l' to return Lighten color. Ex: cl(primary,l)
// Use 'd' to return Darken color. Ex: cl(primary,d)
.test {
color: cl(primary,b);
color: cl(warning,l);
}
Compiled css result:
:root {
--color-primary: #940fe0;
--color-primary-light: #bf61f4;
--color-primary-dark: #550980;
--color-secondary: #e49f38;
--color-secondary-light: #f0ca92;
--color-secondary-dark: #a06916;
--color-warning: #ffe600;
--color-warning-light: #fff066;
--color-warning-dark: #998a00;
--color-info: #165ad6;
--color-info-light: #6395ef;
--color-info-dark: #0c337a;
}
.test {
color: var(--color-primary);
color: var(--color-warning-light);

How to check in SCSS if a variable exists and ha a value?

I am new in SCSS so bear with me :)
I have a use case where a SCSS variable --my-variable can exist and can have a value depending on some settings from the backend. So, if --my-variable exists and has a value I should override some styling. If not I shouldn't override anything.
Example:
In file1 I have:
.my-div {
color: red;
}
In file2 I should have something like this:
.my-div {
#include customize(color, --my-variable);
}
#mixin customize($property, $variable) {
#if $variable and (var($variable)) {
#{$property}: var($variable);
}
}
The problem is that the if condition inside the mixin customize() is always true even if my document has no CSS variable called --my-variable. What am I doing wrong?
Thank you
Sass has a function that check if the variable exists.
variable-exists()
$colorVariable: crimson;
#if variable-exists($colorVariable) {
// Do some styling if the variable exists
}

Unable to use CSS Custom Properties (aka CSS Variables) with SASS #if Statement

I'm trying to pass some CSS Custom Properties to a SASS Mixin. I'm able use the variables when applied directly in the styling I want. But when I try to use a variable in an If statement, it doesn't work.
Mixin Example:
#mixin bg-color($hue, $status) {
background: hsl($hue, 50%, 50%); // $hue works as expected
#if $status == 'danger' { // doesn't work!
color: 'red';
} #else if $status == 'warning' { // doesn't work!
color: 'orange';
} #else { // always enters the else branch
color: 'black';
}
}
CSS:
:root {
--hue: 195;
--status: 'default';
}
.demo {
#include bg-color(var(---hue), var(---status));
}
If I manually add the status value to the mixin, it works:
.demo {
#include bg-color(var(---hue), 'danger');
}
Any idea what might be the issue?
UPDATE: As #temani-afif mentioned, this approach isn't possible because SASS files are compiled before CSS variables are used.
If you have some file, where you import all SCSS files, it depends which is imported first and which are imported after.
Make sure that one that you need to be Read by VS is first.
For example i needed to read first my variables, so it have to be first, other way, my code read mixin, and doesnt know yet what is '$blue'.

Unable to set SCSS variable to CSS variable?

Consider the following SCSS:
$color-black: #000000;
body {
--color: $color-black;
}
When it is compiled with node-sass version 4.7.2, it produces following CSS:
body {
--color: #000000;
}
When I compile the same SCSS with version 4.8.3 or higher, it produces following:
body {
--color: $color-black;
}
What am I missing? I checked release logs, but could not found anything useful. Also, I wonder if this change is genuine why does it have only minor version change? Should it not be a major release?
Also, what is my alternative? Should I use Interpolation?
Just use string interpolation:
$color-black: #000000;
body {
--color: #{$color-black};
}
Apparently the old behaviour is not intended and violated the language specs of SASS:
CSS variables mixed with SCSS variables don't emit proper CSS in 4.8+
CSS variables aren't properly compiled
Assigning SASS variables to CSS Variables (Custom Properties) no longer works
scss and css
I found a workaround to mapping the scss variables to css variables.
See Terry's answer for better use
Scss:
// sass variable map
$colors: (
color-black: #FFBB00
);
// loop over each name, color
:root {
// each item in color map
#each $name, $color in $colors {
--#{$name}: #{$color};
}
}
Css:
:root {
--color-black: #FFBB00;
}
I had an issue with older sass versions.
Trying to compile a list of variables coming from an array, it would get stuck with the double dash. Here's my solution in case it helps someone
$var-element:'--';
:root {
#each $color in $color-variables {
#{$var-element}#{nth($color, 1)}: #{nth($color, 2)};
}
}

SASS Variable within string [duplicate]

This question already has answers here:
Can I use variables for selectors?
(4 answers)
Closed 7 years ago.
Hi all I'm new to SASS (late I know) and playing around with mixins.
Basically is there a way to link a variable to a string here is what I'm trying to do but it throws errors.
(This is a condensed version)
#mixin post-link ($class, $color, $hover) {
a.$class:link {
color: $color;
}
a.$class:hover {
color: $hover;
}
}
Link I say this is a little simpler than what I am trying to do in the mixin (more variables in full one).
EDIT: should add i'm using Compass.
Thanks
Yes, you just have to use variable interpolation. Example:
#mixin post-link ($class, $color, $hover) {
a.#{$class}:link {
color: $color;
}
a.#{$class}:hover {
color: $hover;
}
}
Example on SassMeister: http://sassmeister.com/gist/9533103
The key is adding #{ and } around your variable names to get them expanded.

Resources