search

Home  >  Q&A  >  body text

Generate default values ​​and CSS variables using SCSS

I am implementing website styling.

For legacy support reasons, I need to support IE11, at least for a while. For workflow and my sanity reasons I want to use css variables whenever possible.

I've looked into this solution and it generates something that works, but is rather verbose to use.

My goal is to end up with a hardcoded value that is immediately overridden by a CSS variable. This way I can add a default theme for everyone, and add a different theme (like dark mode) for those browsers that support css variables. I obviously don't need to write all of this myself.

So my idea is that I could write something like this:

$foo {...?}

:root {
  --foo: red;
}

:root.dark {
  --foo: black;
}

p {
  color: $foo;
}

it is translated to

:root {
  --foo: red;
}

:root.dark {
  --foo: black;
}

p {
  color: red;
  color: var(--foo);
}

Can this be achieved using scss? I don't want to bloat this project by adding some random npm modules or other 3rd party compilers and transpilers.

I know it's possible to add a polyfill for IE11 to add support for CSS variables, but most of the ones I've found so far have some form of unfortunate limitation (plus, they're 3rd party which I prefer code) avoid if possible). This is the solution I might go for if there is no good solution using SCSS.

P粉295616170P粉295616170264 days ago574

reply all(1)I'll reply

  • P粉242126786

    P粉2421267862024-04-07 00:07:58

    Here are quick solutions you may want to improve:

    1. Define the map using all colors:
    $colors: ("blue": #0000ff, "red": #ff0000, "green": #00ff00);
    1. Loop through the map to create CSS custom properties:
    @each $color, $value in $colors {
        :root {
            --#{$color}: #{$value};
        }
    }
    1. Create a mixin to output the fallback sum value.
      I decided to create a mixin that takes 2 parameters, the css property and the color you want.
    @mixin propertyPlusColorValue($property, $color) {
        #{$property}: map.get($colors, $color);
        #{$property}: var(--#{$color});
    }
    1. Then you can use it like this:
    .foobar {
        @include propertyPlusColorValue(color, "blue");
        @include propertyPlusColorValue(background-color, "red")
    }

    Full code:

    @use "sass:map";
    
    $colors: ("blue": #0000ff, "red": #ff0000, "green": #00ff00);
    
    @each $color, $value in $colors {
        :root {
            --#{$color}: #{$value};
        }
    }
    
    @mixin propertyPlusColorValue($property, $color) {
        #{$property}: map.get($colors, $color);
        #{$property}: var(--#{$color});
    }
    
    .foobar {
        @include propertyPlusColorValue(color, "blue");
        @include propertyPlusColorValue(background-color, "red")
    }

    reply
    0
  • Cancelreply