ivanwright
ivanwright

Reputation: 311

SASS variables set inside of conditional?

Can I set variables inside of an if / else conditional in SASS? Say for instance you wanted to have 2 color schemes for a page. Thinking in terms of setting a class on the body to handle the color differences, could you do the following (written for English, not attempting any kind of correct syntax):

If parent class is red then $main-color = #f00 else $main-color = #000

Can I do this?

Upvotes: 24

Views: 38741

Answers (4)

Vitalii Andrusishyn
Vitalii Andrusishyn

Reputation: 4162

You can use the function like this:

@function set-color($class) {
  @if ($class == red) {
    @return #f00;
  } @else {
    @return #000;
  }
}
$main-color = set-color($parent-class);

Upvotes: 11

Albaz
Albaz

Reputation: 935

Sass Variable Scope

Sass supports two types of variables: local variables and global variables.

By default, all variables defined outside of any selector are considered global variables. That means they can be accessed from anywhere in our stylesheets. For instance, here’s a global variable:

$bg-color: green;

On the other hand, local variables are those which are declared inside a selector. Later, we’ll examine how we can customize that behavior. But for now, let’s see our first example.

Here we define a mixin and then the btn-bg-color variable within it. This is a local variable, and is therefore visible only to the code inside that mixin:

@mixin button-style {
    $btn-bg-color: lightblue;
    color: $btn-bg-color;
}

Conclusion

you can use this code to make if directive change in your variable

    $left: left;
    $right: right;

@if $dir == rtl { 
     $left: right;
    $right: left;
}
.pull-left{
   float:#{$left};
}

you can read this article Sass Variable Scope

Upvotes: 1

This is how you do it in SASS:

.some-element
  $main-color: black
  color: $main-color

  .red > &
    $main-color: red
    color: $main-color

Resulting CSS:

.some-element {
  color: black;
}
.red > .some-element {
  color: red;
}

But it looks like you're trying to apply a bad solution. Please describe what you're trying to achieve rather than how to implement a solution to an unknown task. See XY problem.

UPD

I thought what I was trying to achieve was pretty clear... but to explain further, I want 2 color schemes for a page. One that's default & one only if the class ".red" is present on the body tag. What you are presenting looks like I would have to set variables for each class and then duplicate for the .red class. I was looking to, basically, have 1 variable (in this case $main-color) that is set for the default and then reset inside the .red class. Make sense?

In SASS there is no way of setting a variable based on whether current code is wrapped in a class or not. You only can declare the variable manually.

You should also understand that what SASS does is generating CSS, nothing more. So let's start from the CSS you would like to have. I assume it's something like this:

header {
  background-color: black; }

#main {
  background-color: black; }

body.red header {
  background-color: red; }

body.red #main {
  background-color: red; }

You should have provided such code in the first place and it's a shame that i have to make blind guesses.

This code can be displayed like this (with the same functionality):

header {
  background-color: black; }

  body.red header {
    background-color: red; }


#main {
  background-color: black; }

  body.red #main {
    background-color: red; }

Now we can see a pattern.

This code can be easily created with SASS using a mixin:

=main-color()
  background-color: black

  body.red &
    background-color: red

Then you apply it like this:

header
  +main-color

#main
  +main-color

Another option is to create a mixin that contains all the styling. This is probably an optimal solution as it contains least duplication.

=theme-styles($main-color: black)
  header
    background-color: $main-color

  #main
    background-color: $main-color

Then you apply it like this:

+theme-styles

body.red
  +theme-styles(red)

In fact, you can generate multiple themes:

+theme-styles

@each $color in red blue green
  body.#{$color}
    +theme-styles($color)

Demo: http://sassbin.com/gist/5812941/

Upvotes: 3

Nick Tomlin
Nick Tomlin

Reputation: 29221

Yes, this is possible:

$parent: true
$foo: red

@if $parent == true 
  $foo: blue

p
  color: $foo

codepen

It's worth noting, however, that you will not be able to use a conditional to check a property on a parent element (or any other element) in SASS (see this post from the SASS lead), so parent class in your psuedo code would have to be stored in a sass $variable.

Upvotes: 17

Related Questions