Search code examples
cssglobal-variablesmixinscss-variablesscss-mixins

Is there any way to make class names the same as the CSS custom variable?


I'm looking for any solution that can reduce this CSS redundancy:

--root {
  --brown: #775E3E;
  --headline: "Big Shoulders Display", "Oswald", "Open Sans", sans-serif;
}

.brown {color: var(--brown);}
.brown-bg {background-color: var(--brown);}

.headline {font-family: var(--headline);}

The end goal is using .headline and .brown classes directly in HTML.

<h1 class="headline brown">I AM BROWN WITH CUSTOM FONT</h1> 

Can this be achieved without having to make an exhausting :root list of colors and then needing to specify each class name (which would be the same) individually?

Basically I want --headline = .headline & --brown = .brown

If there is no simple solution in CSS I am open to using SCSS, a SASS mixin or even javascript. Thank you all in advance!


Solution

  • You can use SCSS for this. I built a snippet for you. It's self descriptive.

    // Arrange them in
    // varName: (type, value)
    $vars: (
      brown: (color, brown),
      headline: (font-family, '"Big Shoulders Display", "Oswald", "Open Sans", sans-serif')
    );
    
    // Turn all those variables to CSS Variables
    :root {
      @each $var, $val in $vars {
        --#{$var}: #{nth($val, 2)};
      }
    }
    
    // Create classes out of those variables
    @each $var, $val in $vars {
      .#{$var} {
        #{nth($val, 1)}: var(--#{$var});
      }
    
      // If type is color then generate a bg color class
      @if nth($val, 1) == color {
        .#{$var}-bg {
          background-color: var(--#{$var});
        }
      }
    }
    

    Then it will generate CSS like this

    :root {
      --brown: brown;
      --headline: "Big Shoulders Display", "Oswald", "Open Sans", sans-serif;
    }
    
    .brown {
      color: var(--brown);
    }
    
    .brown-bg {
      background-color: var(--brown);
    }
    
    .headline {
      font-family: var(--headline);
    }
    

    This is probably what you're looking for. Happy helping.