• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/13/23

Optimize mixins with conditionals in Sass

Truth or dare: using conditionals

Right now, our heading-shadow mixin works really well; unless we plug a dark color into it. The human eye has trouble differentiating between dark colors, so a 10% difference in lightness between lighter colors will be more apparent than the same difference between dark colors.

Once the shadow color gets below a certain threshold, it would make sense to brighten it, rather than darken it. We’re going to make that threshold 25%, so any color that has a lightness of less than 25% will be lightened. Otherwise, if it has a lightness percentage over 25%, we’ll darken it.

In programming, this is called a conditional, or, more commonly, an if/else statement: If the color is less than 25%, lighten it. Else, darken it:

Anatomy of a conditional statement
Anatomy of a conditional statement

Start by typing @if. Then follow it up with your conditional statement: the lightness percentage is less than 25% and a set of curly braces. To get the lightness of  $colour, we are using Sass'  lightness()  function, which returns the color's lightness value:

@if ( lightness($colour) < 25% ) {...}

The conditional statement is evaluated as a true or false question. If the answer is true, do this; if it's false, do something else.

But you want it to do more than just answer the question, right? If your condition is true, you want it to lighten the color. To specify that, you need to put what you want to happen within the curly braces.  In our case, we will use Sass's lighten() function, which will lighten a color by a specified amount, and update $colour with that new value:

@if ( lightness($colour) < 25% ) {
    $colour: lighten($colour, 10%);
}

If the condition is true, Sass will read what’s in the curly brackets and execute the code. But if the answer is false (a color’s lightness percentage is more than or equal to 25%), Sass skips the first set of curly braces and goes straight to the next section of code, which is where we put the “else” part of our if/else statement. Create this by typing @else, and then curly braces containing what to do if the answer is false:

@if ( lightness($colour) < 25% ) {
    $colour: lighten($colour, 10%);
}@else{
    $colour: darken($colour, 10%);
}

So, if the conditional statement is true and $colour's lightness is less than 25%, use the  lighten()  function to lighten it by 10%. But if the statement is false, use the darken() function to darken it 10%.

Let's integrate our if/else statement into our heading-shadow mixin:

@mixin heading-shadow($colour: $colour-primary, $size: $heading-shadow-size){
    @if ( lightness($colour) < 25% ) {
        $colour: lighten($colour, 10%);
    }@else{
        $colour: darken($colour, 10%);
    }
    text-shadow: $size $size $colour;
}

Now let’s put in $colour-secondary, whose value of #001534 has a lightness of 10%. Since 10% is less than 25%, Sass should interpret the conditional statement as true and return #002a67, which is 10% lighter:

.form {
    &__heading {
        @include heading-shadow($colour-secondary);
    }
}
.form__heading {
  text-shadow: 0.55rem 0.55rem #002a67;
}

Success!!

And if we put in a light color? White is just about as light as it gets:

.form {
  &__heading {
    @include heading-shadow($colour-white);
  }
}
.form__heading {
  text-shadow: 0.55rem 0.55rem #e6e6e6;
}

 #E6E6E6 has a lightness of 90%, so our mixin darkened it by 10%, exactly as we wanted. Perfect. 

Conditional statements help keep your codebase flexible and maintainable by automatically adapting blocks of code according to inputs. Flexible and maintainable. Two good things!

Try it out for yourself!

When we hover over our buttons, we can tell that we are hovering only because the cursor changes when the mouse enters and exits the button. Giving a stronger, clearer visual indicator that a user is hovering over our buttons would help to improve our users’ experiences.

In this interactive exercise, let’s give the user some visual feedback by shifting the hue of the button’s background when it’s hovered over. But rather than always shifting the hover state by the same number of degrees, let’s have it be dependent upon the hue of the button’s background color.

If the hue of the button is less than 180 degrees, then we want to increase the hue of the hover color by 30 degrees. But if it’s greater than, or equal to, 180 degrees, we should shift the hue backwards -60 degrees. To get the hue of the button color, we’ll use Sass’ hue() function, which accepts a single color value as an argument, and returns its hue. hue()’s full documentation is available in the Sass documentation.

  • Create a mixin called hover with an argument called $color

  • Create an @if/@else statement with a conditional statement that says if the hue of $color is less than 180

  • Adjust the hue of $color by 30 if the conditional statement is true by using the adjust-hue() function

  • Adjust the hue of $color by -60 if the conditional statement is false

  • Using nesting, the ampersand, and the :hover pseudo-selector, create a hover selector for .btn

  • Include the hover mixin in the .btn:hover selector, with the color value used in .btn’s background property as its argument

Review the rendered webpage, hovering over the button to see the change in color - you can check your answer against this CodePen!

Just dropped in to see what condition my condition is in

Let’s take a closer look at our conditional statement:

( lightness($colour) < 25% )

On the left, is the value that you want to compare, which is the lightness of $colour. On the right, is the value that you want to compare it to, which is 25%. The "less than" symbol ( < ) in the middle is the comparison operator.

A comparison operator is the condition you are comparing the values by: is x less than y? Greater than? Equal to? In all, there are six conditional operators:

Operator

Condition

Result

==

x==y

Returns true if x and y are equal

!=

x!==y

Returns true if x is not equal to y

>

x>y

Returns true if x is greater than y

<

x<y

Returns true if x is less than y

>=

x>=y

Returns true if x is greater than or equal to y

<=

x<=y

Returns true if x is less than or equal to y

And you’re not limited to a single condition.  Let's say you want your condition to return true if  $colour is less than 25%, but also greater than 10%. To evaluate this, you can string together two conditional statements using and to link them together:

@if ( lightness($colour) < 25% ) and ( lightness($colour) > 10% {...}

By using the “and” logical operator, you are requiring that both conditions be true to return true and execute the if block.

You can also use the or logical operator, which will return true if any of the conditions are true.:

@if ( lightness($colour) < 25% ) or ( saturation($colour) > 10% {...}

By using or, whatever is within the curly braces will be executed if either the color has less than 25% lightness or more than 10% saturation.

You can also use if statements by themselves. The else statement is not required. There are times you need to execute code if a condition is true, but if it’s false, you don’t need to do anything, so don’t include an else statement.

Remember, when a conditional statement is evaluated as false, it skips the content in its curly braces and jumps to the next bit of code after that. This can be an @else block of code , or it can just be the rest of your code:

@if ( saturation($colour) < 50% ) {
    $colour: saturation($colour, 50%);
}
background-color: $colour;

There is a conditional statement that checks whether the saturation of $colour is less than 50%, and if it returns true, set the saturation of the color to 50% via Sass' saturation() function.  In essence, there is a minimum to the color saturation of the background color. If it's less than 50%, raise it up to 50%, but if it's already at least 50%, proceed to the next bit of code, which sets the background's color to $colour .

Wait, I'm still not sure I get the difference.  Could you give a different example? 

Let's say that you're driving from your office to your house. With if/else statements, it's like there's construction blocking your route, and they are diverting cars to the left, and heavy trucks to the right. Depending on what you're driving you have to go left or right, but you can't go straight.

With if statements by themselves,  it's like construction is only diverting heavy trucks: cars can keep going straight ahead.

Try it out for yourself!

Let’s take the hover mixin that we created and refine it a touch. Right now, it shifts the hue +30 degrees if the hue is less than 180, and -60 degrees if it is greater than or equal to 180. It’s one way, or another. But we can use more than one conditional statement to create a pocket of values to affect via the @if statement, surrounded by values that return false.

Rather than a singular statement that the hue is less than 180, let’s create a range of values that will return true if the hue is greater than or equal to 135 and less than 180. And for those values, let’s adjust the hue more radically, by 180 degrees, which we can do by the adjust-hue() function, or more simply, the complement() function that automatically returns the complement of the passed color (complements are located 180 degrees away on the color wheel). You can check out the full documentation of the  complement()  function in Sass's documentation.

In this interactive exercise:

  •  Alter the conditional statement contained within the “hover mixin” to state that the hue is greater than or equal to 135: >=

  •  Add a second conditional statement by using the keyword and followed by a statement that the hue is less than ( > ) 180

  • Update the @if operation to use the complement() function, with the background color of the button passed as its argument: $color-primary

Review the rendered page. The value assigned to $color-primary#15DEA5, has a hue of 163 degrees, so the hover color should be its complement, which is pink! You can check your answer against this CodePen, then feel free to adjust the color of $color-primary (such as #19647E) and see how the color of the button’s hover state changes.

Now you have code that’s working! Rather than manually looking at a color and deciding if it should be lightened or darkened, you’ve delegated that decision by giving the code conditions and letting it do the work for you. if/else statements are step-by-step instructions for solving a problem; if it’s like this, do this and then this, or if it’s like that, do this other thing.

The technical term for these instruction manuals is an algorithm. That’s right! You just wrote your first algorithm! 💪

Algorithms are often thought of as extremely complex, obscure blocks of code, and they can be. Facebook's newsfeed algorithm is complex enough to warrant patenting it! But at the most basic level, an algorithm is just an if statement that tells the program how to proceed.

Learning to use conditional statements to control program flow, or how to execute instructions in what order, is a super important step in learning to create flexible and maintainable code

Coming up next, we’ll tidy up our if/else statement by wrapping it up in its own function.

Let's recap!

  • @if  /  @else  statements tell the code how to act depending on if conditions are true or false.

  • They compare two values against a condition, and carry out one set of instructions if it’s true, or another if it’s false.

  • They make code more flexible by allowing it to adapt to changes.

  • @if  statements can be used on their own, without @out

Example of certificate of achievement
Example of certificate of achievement