Making a Sass mixin with optional arguments

2019-01-29 18:11发布

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?

标签: sass
13条回答
Animai°情兽
2楼-- · 2019-01-29 18:22

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;
}
查看更多
贪生不怕死
3楼-- · 2019-01-29 18:23

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

查看更多
走好不送
4楼-- · 2019-01-29 18:25

Old question, I know, but I think this is still relevant. Arguably, a clearer way of doing this is to use the unquote() function (which SASS has had since version 3.0.0):

@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);
}

This is roughly equivalent to Josh's answer, but I think the explicitly named function is less obfuscated than the string interpolation syntax.

查看更多
三岁会撩人
5楼-- · 2019-01-29 18:31

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.

查看更多
ら.Afraid
6楼-- · 2019-01-29 18:32

You can put the property with null as a default value and if you don't pass the parameter it will not be interpreted.

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

This means you can write the include statement like this.

@include box-shadow($top, $left, $blur, $color);

Instead of writing it like this.

@include box-shadow($top, $left, $blur, $color, null);

As shown in the answer here

查看更多
老娘就宠你
7楼-- · 2019-01-29 18:33

here is the solution i use, with notes below:

@mixin transition($trans...) {
  @if length($trans) < 1 {
    $trans: all .15s ease-out;
  }
  -moz-transition: $trans;
  -ms-transition: $trans;
  -webkit-transition: $trans;
  transition: $trans;
}

.use-this {
  @include transition;
}

.use-this-2 {
  @include transition(all 1s ease-out, color 2s ease-in);
}
  • prefer passing property values as native css to stay close to "the tongue"
  • allow passing variable number of arguments
  • define a default value for laziness
查看更多
登录 后发表回答