I have a set of palettes for different themes like so:
$primary: red;
$secondary: blue;
.theme-2 { $primary: green; $secondary: yellow; }
//..
//some random scss file that has typography class names
.cool-text { color: $primary; }
Is it possible to make it so, whatever the class name applied to the container uses the variable palette colors defined for it?
Ex:
<div class="theme-2">
<p class="cool-text"> cool </p> // should be green
</div>
<p class="cool-text"> cool </p> //should be red
Because Sass variables are compiled before runtime, they cannot be context-sensitive, so the example you provided would not be possible.
Some helpful reading with alternate examples here:
https://webdesign.tutsplus.com/articles/understanding-variable-scope-in-sass--cms-23498
And I'd read into native CSS variables, which can do exactly what you want and are gaining support in most browsers aside from IE/Edge:
https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
You can use !default here
check this running code snippet,with your html codepen
$primary: red !default;
$secondary:blue !default;
.cool-text { color: $primary; }
.theme-2 {
$primary: green;
$secondary: yellow;
.cool-text{
color: $primary;
}
}
With this if color is not set to anything ,it would take default red color if not whatever you set it would take that
Hope it helps
Related
I'm currently trying to do a mutliple theme design system with bulma as a base.
But i'm currently struggling with adding a multiple theme system.
I added this in my customstyle scss file but it doesn't seems to work
#charset "utf-8";
:root {
--primary: red;
--secondary: #068295;
}
body[class="light"] {
--primary: #F7A800;
--secondary: #068295;
}
body[class="dark"] {
--primary: blue;
--secondary: #068295;
}
$primary: var(--primary); // this works
$background: blue;
$text-strong: red;
$secondary: #8BC91D; // this works but without theming
// $secondary: var(--secondary); // this doesn't work
$secondary-invert: findColorInvert($secondary) !default;
$custom-colors: (
"secondary":($secondary, $secondary-invert),
);
#import "../node_modules/bulma/sass/utilities/_all.sass";
#import "../node_modules/bulma/sass/base/_all.sass";
#import "../node_modules/bulma/sass/elements/button.sass";
when I run the node sass command to generate the css file
i can see the is-secondary properties generated when i don't use the variable but when i use a variable to define my $secondary variable the is-secondary properties are not generated
I have implemented Angular Material Dark and Light theme. With this I can change the colors based on the theme using for example mat-color($primary). This works fine but now I need to use a different color altogether. So instead of the primary color with hue 200 in light theme: mat-color($primary, 200), I want to be able to use primary color with an 800 hue in dark theme mat-color($primary, 800).
data-table-theme.scss
#mixin data-table-color($color-config) {
$primary: map-get($color-config, primary);
.data-table {
background-color: mat-color($primary, 200);
}
}
data-table.html
<div class="page-container mat-app-background"
[ngClass]="(isDarkTheme$ | async) ? 'theme-dark' : 'theme-default'">
<div class="data-table"></div>
</div>
I tried adding theme-dark selector in custom component style but that didn't work.
#mixin data-table-color($color-config) {
$primary: map-get($color-config, primary);
.theme-default .data-table {
background-color: mat-color($primary, 200);
}
.theme-dark .data-table {
background-color: mat-color($primary, 800);
}
}
I look forward to hearing your solutions.
Edit
The solution I tried doesn't work because angular material generates the css at compile time. So it will then create:
.theme-default .data-table {
background-color: #c5cae9;
}
.theme-dark .data-table {
background-color: #1a237e;
}
.theme-dark .theme-dark .data-table {
background-color: #ff6f00;
}
.theme-dark .theme-default .data-table {
background-color: #ffecb3;
}
This causes it to change hue but the color used is the light primary color.
I have uploaded a test project to Stackblitz, which unfortunately doesn't compile some of the angular material dependencies. But if you run it locally you will see what I mean.
https://stackblitz.com/github/kdrpt/angular-test-project
Have you added the include statement for you mixin in your scss file?
#include data-table-color($color-config);
Just add the above statement in your scss file (where you have defined your #mixin data-table-color) and pass the $color-config that you have created. It is working fine for me.
Looking in your stackblitz example, it seems you forgot to import your app.theme.scss in the root styles.scss.
#import 'theme/app-theme.scss';
Is there a way to override variables in SCSS without mixins or functions?
My setup looks like this:
Input:
$color: red !default;
selector {
color: $color;
}
$color: blue;
Output:
selector {
color: red;
}
I already tried to use !global but this does not work either.
I am not sure, if this is even possible in SCSS without using mixins.
You need to set the variable before it gets declared with !default.
To achieve the result you want your code needs to look like this:
$color: blue;
$color: red !default;
selector {
color: $color;
}
Here is some info about how !default works.
My ultimate goal is to make one template file which i can modify for different pages.
My approach was to create a template.scss and a modifier.scss
in template.scss I set
$background: green;
background: $background
in modifier.scss I set
#import 'template';
$background: red;
and expect the background to change, however nothing happens.
obviously this is the wrong approach, how should i do it?
You are correct in that this approach won't work. Think about how those files would be interpreted.
Example
template.scss
$background: green;
background: $background
modifier.scss
#import 'template';
$background: red;
In this case you're essentially doing:
$background: green;
background: $background
$background: red;
The end effect is background is set to green, and the $background variable is redefined to red in the end.
You would need to define background: $background again within modifier.scss in order for you current setup to work.
A Different Approach
One approach is to define your base styles within one file, modifier styles within another, and then set your CSS properties within a final file. Like this:
template.scss
$background: green;
modifier.scss
$background: red;
styles.scss
background: $background;
You can make that variable a !default in your template.scss and import latter file in a different order in modifier.scss.
Variable Defaults: !default (Sass reference)
In template.scss
$background: green !default;
background: $background;
and then in modifier.scss
$background: red;
#import 'template';
green shouldn't be assigned to the variable if it was already set to red, which is the case in modifier.scss (edit: s/won't/shouldn't I didn't test it yet with partials)
Using this way
variables-template.css (contains variables only)
$background: green;
variables-modifier.css (contains variables only)
$background: red;
styles-template.css (contains your styles)
body { background-color: $background; }
main.css (contains your importation logic)
#import 'variables-template.css';
#import 'variables-modifier.css';
#import 'styles-template.css';
Bonus: Using the Strawberry framework
Strawberry has been created for this kind of situation!
See StrawberrySass.
I don't know how to better name this topic
but idea is the following. I want to show different color for a component depends on a parent class.
for this project I use webpack, vue, vue-loader, sass.
I have a sass file this file contents all settings for pages what color should use for specific page
$colors: ".page-home" blue, ".page-about" green;
#each $i in $colors {
$page: nth($i, 1);
$color: nth($i, 2);
#{$page} .component_1, .component_2, .component_n {
color: $color;
}
}
I have a component is written as vue component
#import "colors";
.compoent_1 {
border:1px solid black
}
A issue is I have a lot of components and it very difficult to support the colors file in consistency. When I want to add a new component or remove an old one I always have to go to this file and edit it is annoying me
So how I see the solution is create a main file.
.page-home:blue;
.page-about: green;
I'd like write components in the following style
.component {
border:1px solid black;
color: $PAGE_COLOR;
}
and this code should generate
.page-home .component_1, .component_2, .component_n {
color: blue;
}
.page-about .component_1, .component_2, .component_n {
color: green;
}
thats all. thanks for any suggestion