Getting into Sass Control Directives

sass_control_header

By Scott O’Hara

Sass makes it very easy to use mixins and extends to write leaner CSS. But perhaps you’re not familiar with how Sass’s Control Directives can help you write leaner Sass.

Using the @if, @for, @each and @while control directives, you can make your Sass take on the brunt of what would otherwise be repetitive style declarations and conditional logic.

Let’s start with @if

The @if control directive is incredibly useful if you need to have situational styling. Basically Sass will check your @if directive, and if the conditions are true, it will output the set CSS. If the conditions do not match, then either no CSS will be compiled, or, if you set up an @else directive, an alternative rule set will be used.

Here’s a simple example:

// Mixin with @if control directive:

@mixin left-or-right($lr) {
  position: absolute;
  top: 0;

  // Declare left or right
  @if $lr == left {
    left: 20px;
  }

  @else if $lr == right {
    right: 20px;
  }
}

In the above mixin the @if directive is set to output different CSS depending on the value of $lr.

// Mixin usage:

.class-name {
  @include left-or-right(left);
}

Here in the example class, the value of $lr is set to left. Which compiles the following:

.class-name {
  position: absolute;
  top: 0;
  left: 20px;
}

Next up: @for

The @for directive is basically a loop that has a start and ending point. You can set @for to either cycle through the loop, or run from a starting point to an ending point.

Using through will run the loop from the first iteration through the end. Using to will run each iteration in the loop until, but not including, the end iteration.

Let’s take a look at a following real-life example to better describe the differences.

// loop to output .txt-h1 - 6
@for $i from 1 through 6 {
  .txt-h#{$i} {
    @extend %txt-h#{$i};
  }
}

In the above example, I’ve setup the @for control directive to generate classes .txt-h1.txt-h6, pulling in silent classes I’ve set up for each type size.

The generated CSS will look like this:

.txt-h1 { ... }
.txt-h2 { ... }
.txt-h3 { ... }
.txt-h4 { ... }
.txt-h5 { ... }
.txt-h6 { ... }

Now, if I had used to instead of through, the generated CSS would have been this:

.txt-h1 { ... }
.txt-h2 { ... }
.txt-h3 { ... }
.txt-h4 { ... }
.txt-h5 { ... }

Each type of the @for directive has it’s use case. Just keep in mind what your output goals are when using the directive.

Thirdly, @each

@each loops through Sass variable lists to generate CSS. If you are unfamiliar with Sass lists, you should really read Hugo Giraudel’s article – it’s very detailed.

By referencing a variable list, the @each directive can then be used to generate code specific to each variable in the list.

A very simple example would be creating a helper class for text aligning.

$align-list: center, left, right;

@each $align in $align-list {
  .txt-#{$align} {
    text-align: $align;
  }
}

Here I’ve created a variable list of the different aligning classes/values I’d like to set. Then, using the @each directive, a new variable $align is created to pull each of the values in the $align-list variable into the directive, until the list completes.

So the compiled CSS looks like:

.txt-center {
  text-align: center;
}

.txt-left {
  text-align: left;
}

.txt-right {
  text-align: right;
}

Finally, @while

The @while directive works similiarly to the @for directive, but instead of going through a list of values, the @while directive will run until the value returns false.

A useful example for the @while directive could be setting up various button sizings.

$btn-sizes: 6;
$btn-padding: 4px;

@while $btn-sizes > 0 {
  .btn-pad-#{$btn-sizes / 2} {
    padding: $btn-padding + $btn-sizes $btn-padding * $btn-sizes;
  }
  $btn-sizes: $btn-sizes - 2;
}

The above code will output the following CSS:

.btn-pad-3 {
  padding: 10px 24px;
}

.btn-pad-2 {
  padding: 8px 16px;
}

.btn-pad-1 {
  padding: 6px 8px;
}

Conclusion

All of the directives here are incredibly simple examples, but hopefully they illustrate how using these directives can end up saving you quite a bit of repetitive CSS. If control directives are completely new to you, then I highly recommend following these examples to build out some simple directives of your own. That way you can get familiar with how to write your own directives and eventually move onto more complex use cases.

Modern Web Newsletter

Subscribe to receive the Modern Web tutorials, sent out every second Wednesday.

  • http://google.com Google John

    Great article thanks.

  • http://ermergingtruths.com Larry Gerndt

    excellent article, easy to comprehend, well exemplified.

  • canciller

    Wow… bookmarked.

  • Pingback: Tweet Parade (no.10 Feb 2014) - Best Articles of Last Week | gonzoblog

  • http://markireland.com.au mark

    Since CSS has style that cascades surely your stylesheet should never be repetitive.

    • # Derek

      i think you missed the point of the article then if you don’t understand how this cuts down on repetition in the Sass files.

  • http://grahamswan.com Graham Swan

    Solid intro to SASS control directives.

    Personally, I appreciate intentional code over clever code. When you come back to debug these stylesheets a few weeks or months from now, parsing a bunch of clever logic is the last thing you’ll want to do.

    For example, I’d rather see the following in code than seeing an array passed into an each-loop that relies on interpolation to produce these simple results:

    .txt-center {
    text-align: center;
    }

    .txt-left {
    text-align: left;
    }

    .txt-right {
    text-align: right;
    }

    • http://scottohara.me Scott

      Hi Graham,

      Thanks for the comment.

      I agree with you actually. The text alignment example was merely just a really simple way to describe the @each directive without getting over complicated with it.

      Over engineering code isn’t the message I wanted people to get from this article, so I’m sorry if that wasn’t clear.

  • http://danyelperales.com Danyel

    Great article. Helped me a lot. Thanks !!

  • Pingback: Doing More with Sass’ @each Control Directive | Flippin' Awesome

  • Pingback: Diacode Weekly #16 | Diacode Blog

Top