LearnSmarter Sass Mixins with Null

Using null in Sass mixins.
   
Avatar

Guil Hernandez
writes on September 4, 2014

With Sass mixins we’re able to pass a list of arguments to set the values of properties. For example, the following mixin uses four variables as arguments to define the display, padding and margin properties of an element.

@mixin display ($disp, $padding, $l-margin, $r-margin) {
  display: $disp;
  padding: $padding;
  margin-left: $l-margin;
  margin-right: $r-margin;
}

When including this mixin, we’ll always need to pass a value for each variable, otherwise it will output an error message.

.nav__link {
  @include display(inline-block, 10px, 20px, 0);
  ...
}

This often forces us to zero out certain properties we don’t need, or unnecessarily redefine their initial values. So, what if we don’t need to pass a value for every variable?

Optional arguments in mixins

Arguments can be optional if we provide default values for them:

@mixin display ($disp, $padding:0, $l-margin:0, $r-margin:0) {
  ...
}

This makes the $padding, $l-margin and $r-margin arguments optional when including the mixin. But again, depending on the values passed, the mixin may output unnecessary CSS, or repeat a lot of code in the output CSS.

Using null

Good news! Sass also supports a null data type, which seems to work best for optional arguments in mixins.

With null, we can pass a variable with no value and it gets excluded from the CSS output unless we assign a value to it when including the mixin. Let’s rewrite the mixin passing null as the default value:

@mixin display (
  $disp, 
  $padding: null, 
  $r-margin: null,
  $l-margin: null) {
    display: $disp;
    padding: $padding;
    margin-left: $l-margin;
    margin-right: $r-margin;
}

The null value works wonderfully in this case because we’re still able to define optional arguments without the unnecessary CSS output. So now, if we pass two values, it will only output those declarations to the CSS.

.nav__item {
  @include display(inline-block, $l-margin: 20px);
}

See null in action in this SassMeister gist:

Play with this gist on SassMeister.

Null with math

Keep in mind that using null in math operations will return an error if no value gets passed. For instance:

@mixin display (
  $disp, 
  $padding: null, 
  $l-margin: null) {
    display: $disp;
    padding: $padding;
    margin-left: $l-margin;
    margin-bottom: $l-margin * 2;
}

.nav__link {
  @include display(inline-block, 10px);
}

This returns an Invalid null operation: "null times 2" error in the output since there’s no value defined for $l-margin––we can’t add, subtract, multiply or divide a number by null.

As we learned, Sass’ null data type is particularly useful for DRYing out a mixin’s CSS output. You can learn more about using null in Sass mixins in our new Advanced Sass course, and in our short course on creating a Compass extension!

GET STARTED NOW

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Get Started

6 Responses to “Smarter Sass Mixins with Null”

  1. Hi,

    What abt can something like the following be done:

    /* Margin mixin */
    @mixin margin-all($top, $right, $bottom, $left)
    { margin-top: $top;
    margin-right: $right;
    margin-bottom: $bottom;
    margin-left: $left; };

    /* Btn mixin */
    @mixin link-btn ($padding, $margin) {
    padding: $padding;
    @include margin-all($margin);
    }

    @include link-btn(20px, (null null 20px null));
    OR
    @include link-btn(20px, ($top:null, $right: null, $bottom: 20px, $left: null));

    If not, how to do it

    • Your code not work correct code is here

      @mixin btn-g($tp,$rm,$lr,$bt){margin-top: $tp; margin-right: $rm; margin-left: $lr; margin-bottom: $bt}
      @mixin btn-p($pp,$mm){padding: $pp; @include btn-g($mm…); }
      .bob2 {@include btn-p(10px,10px 8px 9px 7px); font-family: $font_he01}

  2. I love the simple approach to this. I am always compelled to put in a default, even if the parameter is optional. Null seems to be the most streamlined approach for values that might or might not be present, but the whole math issue will come back to bite me every once in awhile. That’s why I opt to put in ($foo: false) and do an @if check instead. Maybe a little overly robust at times, but has saved me future hassle.

    All in all, great article. Cheers, Guil!

  3. Another way to handle the “null with math” issue is to wrap each of your mathed outputs in an if statement. Makes for longer mixins but fewer errors:

    @if $s-margin {
    margin-bottom: $l-margin * 2;
    }

    Sassmeister Gist: http://sassmeister.com/gist/e99e8e31c05e98c6104a

  4. Bruno Seixas on September 4, 2014 at 9:25 am said:

    Great, wasnt aware of the null feature =)

Leave a Reply

You must be logged in to post a comment.

man working on his laptop

Are you ready to start learning?

Learning with Treehouse for only 30 minutes a day can teach you the skills needed to land the job that you've been dreaming about.

Start a Free Trial
woman working on her laptop