Dynamic Sass Variables
This is basic theming. You would either want to use a mixin or include to do multiple themes in a single CSS file. This is how you would go about it using includes:
_theme.scss
section.accent {
background: $accent;
}
.foo {
border: $base;
}
.bar {
color: $flat;
}
main.scss
html {
&.sunrise {
$accent: #37CCBD;
$base: #3E4653;
$flat: #eceef1;
@import "theme";
}
&.moonlight {
$accent: #18c;
$base: #2a2a2a;
$flat: #f0f0f0;
@import "theme";
}
}
You could just as easily make a mixin that takes 3 colors as its arguments to use in place of the include:
@mixin theme($accent, $base, $flat) {
// .. do stuff ..
}
Set a variable in Sass depending on the selector
I think a mixin is the answer. (As I wrote, variables won’t work.)
@mixin content($color-default, $color-main) {
background: $color-default;
color: $color-main;
}
body.class-1 {
@include content(#444, #555);
}
body.class-2 {
@include content(#666, #777);
}
That SCSS compiles to this CSS:
body.class-1 {
background: #444444;
color: #555555; }
body.class-2 {
background: #666666;
color: #777777; }
If you wanted to group the color values together in your SCSS file, you could use variables in conjunction with the mixin:
$color-1: #444;
$color-2: #555;
$color-3: #666;
$color-4: #777;
body.class-1 {
@include content($color-1, $color-2);
}
body.class-2 {
@include content($color-3, $color-4);
}
SASS Customize Class Names with Variables
Yes it is possible with the help of variable interpolation or variable substitution
which uses #{}
for variable substitution in SASS and mixins
which is a block of code just like function.
Interpolation is the process of evaluating an expression or a string containing one or more variables, yielding a result in which the variables are replaced with their corresponding values.
Simple example of interpolation and set values to the css property in SASS:
$number:60;
$n: 20px;
.m-b-#{$number}{
margin-bottom: #{$number}px;
margin-top: $n;
}
To create customize class names, will use mixins:
@mixin margin-class($side, $number) {
$firstLetter: str-slice($side, 0, 1);
.m-#{$firstLetter}-#{$number}{
margin-#{$side}: #{$number}px;
}
}
$margins: (10, 20);
$sides: ("top", "right", "bottom", "left");
@mixin generate-margin(){
@each $margin in $margins{
@each $side in $sides{
@include margin-class($side, $margin);
}
}
}
@include generate-margin();
Here, generate-margin()
will get executed which will call margin-class()
for each $margins
and $sides
, and will generate the below CSS classes:
.m-t-10 {
margin-top: 10px;
}
.m-r-10 {
margin-right: 10px;
}
.m-b-10 {
margin-bottom: 10px;
}
.m-l-10 {
margin-left: 10px;
}
.m-t-20 {
margin-top: 20px;
}
.m-r-20 {
margin-right: 20px;
}
.m-b-20 {
margin-bottom: 20px;
}
.m-l-20 {
margin-left: 20px;
}
That's the one way when you want only for specific values, but if you want to create margin class for 0-20, you can loop thru 0 to 20 as shown below:
@mixin generate-margin(){
@for $margin from 1 through 20{
@each $side in $sides{
@include margin-class($side, $margin);
}
}
}
Define variables in Sass based on classes
No. What you're asking for would require Sass to have knowledge of the DOM. Sass only compiles directly to CSS, it is never sent to the browser.
With your sample code, all you're doing is overwriting $basicFont
every time. In version 3.4 or later, your variable will only exist within the scope of the block where it was set.
So, your only real options are to make use of mixins or extends.
Extend
This is effective, but is only suitable for very simple cases.
%font-family {
&.one {
font-family: Verdana, sans-serif;
}
&.two {
font-family: Tahoma, sans-serif;
}
}
.foo {
@extend %font-family;
}
Output:
.one.foo {
font-family: Verdana, sans-serif;
}
.two.foo {
font-family: Tahoma, sans-serif;
}
Mixin
This is the method I would recommend if you want a little more fine grained control over which variables are used where.
$global-themes:
( '.one': ('font-family': (Verdana, sans-serif), 'color': red)
, '.two': ('font-family': (Tahoma, sans-serif), 'color': blue)
);
$current-theme: null; // don't touch, this is only used by the themer mixin
@mixin themer($themes: $global-themes) {
@each $selector, $theme in $themes {
$current-theme: $theme !global;
{$selector} {
@content;
}
}
}
@function theme-value($property, $theme: $current-theme) {
@return map-get($theme, $property);
}
.foo {
@include themer {
font-family: theme-value('font-family');
a {
color: theme-value('color');
}
}
}
Output:
.foo.one {
font-family: Verdana, sans-serif;
}
.foo.one a {
color: red;
}
.foo.two {
font-family: Tahoma, sans-serif;
}
.foo.two a {
color: blue;
}
Using css variables correct way
I think you're mixing (no pun intended) CSS up with SASS/SCSS or other CSS pre-processors.
@mixin
is used by CSS pre-processors and not native CSS. In that case you declare mixins the way you're doing, and variables like:
$main-bg-color: brown;
@mixin themeChanges-background {
background-color: $main-bg-color;
}
.classOne {
ul {
@include themeChanges-background;
}
}
In native CSS, mixins are done just like your other variables:
:root {
--main-bg-color: brown;
--themeChanges-background: {
background-color: var(--main-bg-color);
}
}
.classOne {
ul {
@apply --themeChanges-background;
}
}
There's just one little catch, @apply
is an experimental feature and isn't supported by any browsers out of the box. You can enable it in Chrome with the "Experimental web platform features" feature flag if you really want. I recommend sticking with SASS or SCSS though if you want any one else to see your styles.
Related Topics
I Need Help Making CSS for a Modern Vertical Navbar
Difference Between These Two Style Rules
Postcss - Color Function Plugin - "Unable to Parse Color from String"
Get Child Element to Respect Parent Element Width & Height
Website Will Not Scroll on Mobile Devices
A Mnemonic for The Order of CSS Margin and Padding Shorthand Properties
How to Refer to an Internal Gradient Definition Inside an Svg Sprite Symbol
<Hr> Inside Container with Display Flex Become Corrupted
Why Is My Bootstrap Column Centered Instead of Left-Aligned
Facebook Like Button - How to Disable Comment Pop Up Box
Style The Tawk.To Chat Widget with My Custom CSS
Creating a Fixed Background for a Website
How to Create Variable Columns and Fill Them Up
Remove The Bottom Margin of a Handsontable
Li:Before{ Content: "■"; } How to Encode This Special Character as a Bullit in an Email Stationery