Is There Any Possibilty Using CSS-Variables in Sass

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



Leave a reply



Submit