Search code examples
sassinterpolationmixins

Sass interpolate a variable name to string


We were provided a number of colors with specific hover-state colors associated:

$red: #cb333b;
$red-hover: #fe666e;
$brown: #544742;
$brown-hover: #877a75;
etc.

Since all the colors are formatted the same way, so I was hoping to write a mixin that takes the color's variable name, then concatenates -hover to the end. This is my first try:

@mixin button_colorizor($color) {
  border-color: $color;
  color: $color;
  &:hover {
    color: #{$color}-hover;
    border-color: #{$color}-hover;
  }
}

But what this does is output a color like this: #f1735f-hover. The same thing when I do this: color: #{$color+-hover};


Solution

  • You can create map of colors. And get color values by its names.

    Demo on sassmeister.

    $colors: (
      red: #cb333b,
      red-hover: #fe666e,
      brown: #544742,
      brown-hover: #877a75
    );
    
    @mixin button_colorizor($color) {
      color: map-get($colors, $color);
      border-color: map-get($colors, $color);
    
      &:hover {
        color: map-get($colors, $color + '-hover');
        border-color: map-get($colors, $color + '-hover');
      }
    }
    
    a {
      @include button_colorizor(red);
    }
    
    span {
      @include button_colorizor(brown);
    }
    

    This code is compiled to css:

    a {
      color: #cb333b;
      border-color: #cb333b;
    }
    a:hover {
      color: #fe666e;
      border-color: #fe666e;
    }
    
    span {
      color: #544742;
      border-color: #544742;
    }
    span:hover {
      color: #877a75;
      border-color: #877a75;
    }