rekam
rekam

Reputation: 1121

Set a SASS variable depending

I'm searching a way to use a particular color depending on a class on the body tag.

I have a main scss file like this

// variables.scss
$bg-main:      white;
$color-first:  red;
$color-second: green;

And in my other files, I use the colors

// content.scss
.content {
     .some-selector: {
         // some styles
         color: $color-second;
     }
     a:hover {
         // some styles
         color: $color-second;
     }
}    

// and same goes for menu.scss etc.

Now I have a dynamic class on the body, that changes depending on the current selected menu. I would like $color-second to be different for each body classes, and I don't know how to do that. The only solution I found was to move all the $color-second from each files into one single file, like this:

.body-1 {
    .content a:hover, .content .some-selector {
        color: green;
    }
}
.body-2 {
    .content a:hover, .content .some-selector {
        color: blue;
    }
}
.body-1 {
    .content a:hover, .content .some-selector {
        color: black;
    }
}

So I don't need to write the color in each files. This works well, but if I need to set this $color-second to some other selector, I need to put that in this big file.

Is this possible to do this an other way?

I already checked these answers, but it didn't helped me much:

Upvotes: 1

Views: 2474

Answers (1)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34189

There are multiple ways to do this. The most obvious two which come to mind are mixins and loops:

Mixins

Just put everything you want into a single mixin, and then use it for every body class:

@mixin colored-content($color) {
  .content a:hover, .content .some-selector {
      color: $color;
  }

  /* Any other rules which use $color here */
}

.body-1 {
  @include colored-content(green);
}

.body-2 {
  @include colored-content('#FF0000');
}

.body-3 {
  @include colored-content(darken(red, 20));
}

You can extend this example with any number of arguments (for example, $textColor and $bgColor), conditions or rules.

With this approach you will not have SCSS code repetitions, and any updates will be introduced easily.

Loop

Another way is to use a simple loop:

$body_themes: (
    "body-1": green,
    "body-2": #FF0000,
    "body-3": darken(red, 2)
);

@each $body_class, $color in $body_themes {
  .#{$body_class} {
    .content a:hover, .content .some-selector {
      color: $color;
    }

    /* Any other rules which use $color here */
  }
}

It is even shorter, but imho it is less readable.

P.S. It is possible to combine mixins and loops, by the way :)

Upvotes: 1

Related Questions