使用可选参数进行Sass mixin


201

我正在写一个像这样的mixin:

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

当真正被调用时,我真正想要的是如果不$inset传递任何值,则不会输出任何内容,而是将其编译为以下内容:

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

如何重写mixin,以便在没有$inset传递值的情况下什么也不输出?


6
可惜SASS没有blankor或nilvalue。
约书亚·品特

1
顺便说一句,在研究不同的SASS限制时,我遇到了一种很好的方法来消除这些情况下的引号。我为此添加了答案。
约书亚·品特

4
现在在2015年,您可以使用null来跳过attr / prop。ie @include box-shadow($top, $left, $blur, $color, null)
下降

Answers:


257

一种干燥的方式

而且,通常,这是删除引号的巧妙方法。

@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版本3+,您可以使用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);
} 

在这里进行选择:使用SASS作为单个参数将列表传递给mixin


6
正如Bob Sammers指出的那样,在较新版本的SASS中,您也可以使用unquote()方法代替#{}来删除引号。干杯。
Joshua Pinter13年

4
最简单的方法是使用null可选参数的默认值代替"",它们不会在输出中呈现!@mixin box-shadow($top, $left,... , $inset:null) {}
S.Serpooshan

@ S.Serpooshan我很好奇它添加了什么版本。2012
Joshua Pinter

79

更好的干法

是传递$args...给的@mixin。这样,无论$args您要通过多少次。在@input通话中,您可以传递所有需要的参数。像这样:

@mixin box-shadow($args...) {
  -webkit-box-shadow: $args;
  -moz-box-shadow: $args;
  box-shadow: $args;
}

现在,您可以通过传递所有需要的参数,在每个所需的类中重用盒子阴影:

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

11
很高兴知道这一点,但通常更清楚地表明a mixin期望什么参数,例如$top$left$blur等可变参数,就像你所展示的,是伟大的最大的灵活性,虽然。
约书亚·品特

1
谢谢,伙计,它对我有很大帮助
Nilesh Sutar

48

Sass支持@if语句。(请参阅文档。)

您可以这样编写mixin:

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

这在这里没有用,只有当该inset部分为null时,才必须将其排除,而不是将所有框阴影属性都排除在外
S.Serpooshan

@ S.Serpooshan只需添加else并在其中包含所有非插入属性。
mbomb007 '18

@ mbomb007我知道,我只是报告此解决方案有问题。上面提供的其他答案绝对更好。
S.Serpooshan

26

您可以将属性设置为null作为默认值,如果不传递该参数,它将不会被解释。

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

这意味着您可以这样编写include语句。

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

而不是像这样写。

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

如图答案在这里


1
此答案没有提供比现有答案新的内容(请参阅:stackoverflow.com/a/23565388/1652962
cimmanon

9
@cimmanon相反,这提供了额外的实用程序,您可以随后使用@include box-shadow($top, $left, $blur, $color);代替编写导入@include box-shadow($top, $left, $blur, $color, null);。因此,这个答案更为有益。

1
@Dan这样做实际上会使您失去可读性,因此可以说,它比从其得出的答案中受益更少
TylerH

@TylerH是真的
Dan

14

我知道这个老问题,但是我认为这仍然有意义。可以说,更清晰的方法是使用unquote()函数(SASS自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);
}

这大致相当于Josh的答案,但是我认为显式命名的函数比字符串插值语法更容易混淆。


12

我知道它不完全是您要寻找的答案,但是您可以"null"在进行@include box-shadow混合时作为最后一个参数传递,像这样@include box-shadow(12px, 14px, 2px, green, null);现在这样,如果那个参数在该属性中只有一个,则该属性(及其(默认)值)不会被编译。如果该“行”上有两个或多个参数,则只有您为空的参数不会被编译(您的情况)。

CSS输出完全如您所愿,但是您必须编写nulls :)

  @include box-shadow(12px, 14px, 2px, green, null);

  // compiles to ...

  -webkit-box-shadow: 12px 14px 2px green;  
  -moz-box-shadow: 12px 14px 2px green;  
  box-shadow: 12px 14px 2px green;

1
毫无疑问,我最喜欢的方法是使所有内容在必须返回脚本时都易于阅读和理解。thnx滴。
Plentybinary

7

这是我使用的解决方案,以下说明:

@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);
}
  • 宁愿将属性值作为本地css传递,以保持接近“舌头”
  • 允许传递可变数量的参数
  • 定义懒惰的默认值

如何在现有答案(即stackoverflow.com/a/28072864/1652962)上添加任何内容?
cimmanon

他解释了如何判断是否将多个参数传递给该函数,如果是,则更改输出。另一个答案没有。
TetraDev 2015年

有时,您想定义全局行为。例如,在动画过渡时,您通常希望获得非常统一的体验,并且在决定做什么时不希望冒险承担“创造性的开发人员酌处权”。这定义了一个可以覆盖的默认值,但是由于不传递参数时语法更紧凑,因此通常不会被覆盖。您还可以通过这种方式在一个地方更改全局行为。
duggi

3

使用sass@3.4.9:

// declare
@mixin button( $bgcolor:blue ){
    background:$bgcolor;
}

且没有价值的使用,按钮将变为蓝色

//use
.my_button{
    @include button();
}

并带有值,按钮将为红色

//use
.my_button{
    @include button( red );
}

也与六合一


如何在现有答案之外添加任何内容?
cimmanon

3

更干燥的方式!

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

现在,您可以更聪明地重用盒子阴影了:

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

只是一个注释-像这样可读,我也承认,这是在DRY代码和可读性/可维护性之间划清界限的地方。
利奥·拿破仑

我同意,为了提高可读性/可维护性,我将创建一个“浏览器列表”以在其他mixin中重用。这也可以很容易地组装到其他css属性中,这些属性可以用一组干mixins来执行。2014年的这篇文章仍然是一个很好的例子。
Ben Kalsky

1
@mixin box-shadow($left: 0, $top: 0, $blur: 6px, $color: hsla(0,0%,0%,0.25), $inset: false) {
    @if $inset {
        -webkit-box-shadow: inset $left $top $blur $color;
        -moz-box-shadow: inset $left $top $blur $color;
        box-shadow: inset $left $top $blur $color;
    } @else {
        -webkit-box-shadow: $left $top $blur $color;
        -moz-box-shadow: $left $top $blur $color;
        box-shadow: $left $top $blur $color;
    }
}

由于它的冗长性,这可以说比所有其他答案都差。而且,它与其他答案之一足够接近,可以算作重复项。
cimmanon 2014年

1

超级简单的方法

只需将默认值添加none到$ inset-这样

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

现在,当没有传递$ inset时,将不会显示任何内容。


1

您始终可以将null分配给可选参数。这是一个简单的解决方法

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

0

我是CSS编译器的新手,希望能对您有所帮助,

        @mixin positionStyle($params...){

            $temp:nth($params,1);
            @if $temp != null{
            position:$temp;
            }

             $temp:nth($params,2);
            @if $temp != null{
            top:$temp;
            }

             $temp:nth($params,3);
            @if $temp != null{
            right:$temp;
            }

             $temp:nth($params,4);
            @if $temp != null{
            bottom:$temp;
            }

            $temp:nth($params,5);
            @if $temp != null{
            left:$temp;
            }

    .someClass{
    @include positionStyle(absolute,30px,5px,null,null);
    }

//output

.someClass{
position:absolute;
 top: 30px;
 right: 5px;
}

如何在现有答案之外添加任何内容?
cimmanon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.