Making a Sass mixin with optional arguments

Viewed 167667

I am writing a mixin like this:

@mixin box-shadow($top, $left, $blur, $color, $inset:"") {
    -webkit-box-shadow: $top $left $blur $color $inset;
    -moz-box-shadow: $top $left $blur $color $inset;
    box-shadow: $top $left $blur $color $inset;
}

When called what I really want is that if no $inset value is passed, nothing is output, rather than it compiling to something like this:

-webkit-box-shadow: 2px 2px 5px #555555 "";
-moz-box-shadow: 2px 2px 5px #555555 "";
box-shadow: 2px 2px 5px #555555 "";

How do I rewrite the mixin so that if there is no value of $inset passed, nothing is output?

13 Answers

A DRY'r Way of Doing It

And, generally, a neat trick to remove the quotes.

@mixin box-shadow($top, $left, $blur, $color, $inset:"") {
  -webkit-box-shadow: $top $left $blur $color #{$inset};
  -moz-box-shadow:    $top $left $blur $color #{$inset};
  box-shadow:         $top $left $blur $color #{$inset};
}

SASS Version 3+, you can use unquote():

@mixin box-shadow($top, $left, $blur, $color, $inset:"") {
  -webkit-box-shadow: $top $left $blur $color unquote($inset);
  -moz-box-shadow:    $top $left $blur $color unquote($inset);
  box-shadow:         $top $left $blur $color unquote($inset);
} 

Picked this up over here: pass a list to a mixin as a single argument with SASS

Even DRYer way!

@mixin box-shadow($args...) {
  @each $pre in -webkit-, -moz-, -ms-, -o- {
    #{$pre + box-shadow}: $args;
  } 
  #{box-shadow}: #{$args};
}

And now you can reuse your box-shadow even smarter:

.myShadow {
  @include box-shadow(2px 2px 5px #555, inset 0 0 0);
}

Super simple way

Just add a default value of none to $inset - so

@mixin box-shadow($top, $left, $blur, $color, $inset: none) { ....

Now when no $inset is passed nothing will be displayed.

You can always assign null to your optional arguments. Here is a simple fix

@mixin box-shadow($top, $left, $blur, $color, $inset:null) { //assigning null to inset value makes it optional
    -webkit-box-shadow: $top $left $blur $color $inset;
    -moz-box-shadow: $top $left $blur $color $inset;
    box-shadow: $top $left $blur $color $inset;
}
Related