开发者

Is it possible to overload mixins in sass?

Let say you have a mixin for shadow like such:

@mixin box-shadow($offset, $blur, $color)
{
   -moz-box-shadow: $offset $offset $blur $color;
   -webkit-box-shadow: $offset $offset $blur $color;
   box-shadow: $offset $offset $blur $color;
}

Is it possible to overload that mixin with something like:

@mixin box-shadow($offset, $blur)
{
    @include box-shadow($offset, $blu开发者_如何学Cr, #999);
}

Or do I have to use different names for the mixins?


You can't overload, but the typical practice would be to set defaults.

 /* this would take color as an arg, or fall back to #999 on a 2 arg call */
 @mixin box-shadow($offset, $blur, $color: #999) {
   -webkit-box-shadow: $offset $offset $blur $color;
   -moz-box-shadow: $offset $offset $blur $color;
   box-shadow: $offset $offset $blur $color;
 }


If you need to tweak a vendor mixin slightly you can copy it to another file - included after the original - and edit it in there, and the vendor's original will be ignored.

@import "_their-mixins";
@import "_our-mixins";

Warning - this may depend on which processor you are using. At time of writing it works great using grunt and grunt-contrib-compass


@numbers1311407 solution is correct, but you can use the @each directive to create a shorter mixin:

@mixin box-shadow($offset, $blur, $color: #999) {
  @each $prefix in -moz-, -webkit-, null {
    #{$prefix}box-shadow: $offset $offset $blur $color;
  }
}


Or you can use a very simple yet effective approach to fake overloading:

@mixin abc2($a, $b) {
  a: $a;
  b: $b;
}
@mixing abc3($a, $b, $c) {
  @include abc2($a, $b);
  c: $c;
}

You can streamline it you can just add the number of arguments expected as integer after the mixins name.

To make this connotation work with unknown number of arguments, you can extend it with an underscore, implying an unknown number (including 0) number of arguments.

@mixin abc3_($a, $b, $c, $d...) {
  // expects at least 0 arguments for $d, so at least 3 in total
}
@mixin abc4_($a, $b, $c, $d...) {
  // expects at least 1 argument for $d, so at least 4 in total
}

For mixins without overloading you can leave the integer, implying there is only one interface.

In case you are using mixins with trailing integers already you can change "NAME#" to "NAME_#" instead to allow "NAME1_#" to still keep your old connotation in place and just extend it without replacing it.

The upside is that your code is much cleaner and easier to read. However, the downside is that you have to consider an unorthodox syntax. Depeding on your complexity this however might be much more effective.

You can even combine both in providing and interface without integers and in the background using functions with integers.

@mxin abc($a, $b, $c: null) {
  @if ($c == null) {
    @include abc2($a, $b);
  } @else {
    @include abc3($a, $b, $c);
  }
}

This way you can keep the code pretty clean and easy while not needing to use a huge amount of if/else statements inside a single mixin. If you put your sub mixins in a different file then it's also easy to keep clean.

If it makes sense depends sightly on the complexity of the mixins you are going to create. The more complex they are, the better they should be encapsulated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜