İsteğe bağlı argümanlar ile bir Sass karışımı yapmak


203

Ben böyle bir mixin yazıyorum:

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

Gerçekten istediğim olarak adlandırıldığında, hiçbir $insetdeğer geçirilmezse, bunun gibi bir şeye derleme yerine hiçbir şey çıktı değildir:

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

$insetGeçirilen değer yoksa hiçbir şeyin çıktı alınmaması için mixini nasıl yeniden yazarım ?


6
SASS'ın bir değeri blankveya nildeğeri olmayan bir utanç .
Joshua Pinter

1
Btw, farklı bir SASS sınırına bakarken, bu durumlarda alıntılardan kurtulmak için güzel bir yolla karşılaştım. Bunun için bir cevap ekledim.
Joshua Pinter

4
Şimdi 2015'te sadece nullattr / prop'i atlamak için kullanabilirsiniz . ie @include box-shadow($top, $left, $blur, $color, null)
Damla

Yanıtlar:


258

DRY'r Yapmanın Yolu

Ve genellikle, tırnak kaldırmak için temiz bir hile.

@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 Sürüm 3+, şunları kullanabilirsiniz 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);
} 

Bunu buradan aldık: SASS ile tek bir argüman olarak bir karışıma bir liste iletin


6
Bob Sammers'ın işaret ettiği gibi, SASS'ın daha yeni sürümünde, tırnak işaretlerini kaldırmak için # {} yerine unquote () yöntemini de kullanabilirsiniz. Şerefe.
Joshua Pinter

4
En basit yol, nullyerine isteğe bağlı parametrelerin varsayılan değeri için kullanmaktır ""ve çıktıda işlenmezler! @mixin box-shadow($top, $left,... , $inset:null) {}
S.Serpooshan

@ S.Serpooshan Bunun hangi sürüme eklendiğini merak ediyorum. Bu kesinlikle 2012'de desteklenmedi.
Joshua Pinter

79

Çok daha iyi KURU bir yol

geçmektir $args...için @mixin. Bu şekilde, kaç tane $argsgeçeceğiniz önemli değil. Gelen @inputçağrı, size gerekli tüm args geçebilir. Şöyle ki:

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

Ve şimdi gerekli tüm argümanları ileterek kutu gölgenizi istediğiniz her sınıfta yeniden kullanabilirsiniz:

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

11
'S iyi biliyorum ama çoğu kez o bir şey argümanlar göstermek için daha açık mixingibi bekliyor $top, $left, $blurgösterdiğin gibi, vb Değişken argümanlar, nihai esneklik için mükemmeldir olsa.
Joshua Pinter

1
Teşekkürler, dostum bana çok yardımcı oluyor
Nilesh Sutar

48

Sass @ififadeleri destekler . ( Belgelere bakın .)

Mixininizi şöyle yazabilirsiniz:

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

Burada yararlı değildir, sadece insetkutu null olduğunda değil , yalnızca bölüm null olduğunda hariç tutulmalıdır
S.Serpooshan

@ S.Serpooshan Sadece içine ekleyin elseve içeride olmayan tüm özellikleri ekleyin .
mbomb007

@ mbomb007 biliyorum, sadece bu çözümle ilgili bir sorun rapor ediyorum. Ve yukarıda verilen diğer cevaplar kesinlikle daha iyidir.
S.Serpooshan

26

Özelliği null ile varsayılan değer olarak koyabilirsiniz ve parametreyi geçmezseniz yorumlanmaz.

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

Bu, include deyimini böyle yazabileceğiniz anlamına gelir.

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

Böyle yazmak yerine.

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

Buradaki cevapta gösterildiği gibi


1
Bu cevap mevcut cevaplar hakkında yeni bir şey
sunmuyor

9
@cimmanon Aksine, daha sonra @include box-shadow($top, $left, $blur, $color);bunun yerine içe aktarmayı yazabileceğiniz için ekstra bir yardımcı program sağlar @include box-shadow($top, $left, $blur, $color, null);. Bu nedenle bu cevap çok daha yapay.
Dan

1
@Dan Aslında bu şekilde okunabilirliği kaybedersiniz, bu yüzden tartışmasız türetildiği cevaptan daha az faydalıdır.
TylerH

@TylerH Bu doğru
Dan

14

Eski soru, biliyorum, ama bunun hala geçerli olduğunu düşünüyorum. Muhtemelen, bunu yapmanın daha açık bir yolu unquote () işlevini kullanmaktır (SASS'ın 3.0.0 sürümünden beri sahip olduğu):

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

Bu kabaca Josh'un cevabına eşdeğerdir, ancak açıkça adlandırılan işlevin dize enterpolasyonu sözdiziminden daha az şaşırmış olduğunu düşünüyorum.


12

Ben tam olarak aradığınız cevap değil biliyorum ama mixin "null"zaman son argüman olarak @include box-shadow, bu gibi @include box-shadow(12px, 14px, 2px, green, null);Şimdi geçebilir , eğer bu argüman sadece bir özellik (ve (varsayılan) değeri) bu özellik daha derlenmiş olmazsa . Eğer bu "satırda" iki veya daha fazla argüman varsa, sadece boş bıraktığınız olanlar derlenmeyecektir (davanız).

CSS çıktısı tam olarak istediğiniz gibi, ama sizin nulls yazmak zorunda :)

  @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
Kesinlikle bunu yapmanın en sevdiğim yolu, bir senaryoya geri dönmeniz gerektiğinde her şeyi okumak ve anlamak için basit tutar. thnx Damlalar.
Mart'ta Plentybinary

7

İşte aşağıdaki notları ile kullandığım çözüm:

@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);
}
  • "dil" e yakın kalmak için özellik değerlerini yerel css olarak geçirmeyi tercih edin
  • değişken sayıda bağımsız değişken geçirilmesine izin ver
  • tembellik için varsayılan bir değer tanımlama

Bu mevcut cevaplara nasıl bir şey ekler (yani: stackoverflow.com/a/28072864/1652962 )?
cimmanon

İşleve birden fazla argümanın aktarılıp aktarılmadığını nasıl anlayacağımızı ve varsa çıktıyı nasıl değiştireceğini açıkladı. Diğer cevap vermedi.
TetraDev

bazen küresel bir davranış tanımlamak istersiniz. örneğin, genellikle çok düzgün bir deneyim yaşamak istediğiniz ve ne yapacağınıza karar verme konusunda "yaratıcı geliştiricinin takdirine bağlı" risk almak istemediğiniz animasyon geçişleri. bu, geçersiz kılınabilecek ancak bağımsız değişkenler geçirilmediğinde daha kompakt sözdizimi nedeniyle olmayacak bir varsayılan tanımlar. global davranışı tek bir yerden bu şekilde değiştirebilirsiniz.
duggi

3

Sass@3.4.9 ile:

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

ve değersiz kullanın, düğme mavi olacak

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

ve değer ile, düğme kırmızı olacaktır

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

hexa ile de çalışır


Bu mevcut cevapların üzerine nasıl bir şey ekliyor?
cimmanon

3

DRYer bile!

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

Ve şimdi kutu gölgenizi daha akıllıca tekrar kullanabilirsiniz:

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

Sadece bir not - bu kadar okunabilir ve ben bunu kabul ediyorum, bu nerede bir DRY kodu ve okunabilirlik / sürdürülebilirlik arasındaki çizgi çizmek gerekir .
Leo Napolyon

Okunabilirliği / sürdürülebilirliği artırmak için diğer karışımlarda yeniden kullanmak üzere bir "tarayıcı listesi" oluşturacağımı kabul ediyorum . Bu aynı zamanda bir dizi kuru karışımla yürütülebilen diğer css özelliklerine de monte edilebilir. 2014'ten bu makale hala harika bir örnek.
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;
    }
}

Bu tartışmalı olması nedeniyle diğer tüm cevaplardan daha kötüdür. Ayrıca, yinelenen saymak için diğer cevaplardan birine yeterince yakın .
cimmanon

1

Süper basit yol

none$ İnset için varsayılan bir değer eklemeniz yeterlidir.

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

Şimdi $ inset girilmezse hiçbir şey gösterilmez.


1

İsteğe bağlı bağımsız değişkenlerinize her zaman null atayabilirsiniz. İşte basit bir düzeltme

@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 derleyicilerinde yeniyim, umarım bu yardımcı olur,

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

Bu mevcut cevapların üzerine nasıl bir şey ekliyor?
cimmanon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.