Tworzenie miksu Sass z opcjonalnymi argumentami


201

Piszę taki 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;
}

Po wywołaniu tak naprawdę chcę, aby jeśli żadna $insetwartość nie została przekazana, nic nie jest generowane, zamiast kompilacji do czegoś takiego:

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

Jak przepisać mixin, aby jeśli nie $insetprzekazano żadnej wartości , nic nie zostanie wyświetlone?


6
Szkoda, że ​​SASS nie ma wartości blankani nil.
— Joshua Pinter

1
Przy okazji, patrząc na inne ograniczenie SASS, znalazłem dobry sposób na pozbycie się cytatów w takich sytuacjach. Dodałem odpowiedź na to.
— Joshua Pinter

4
Teraz w 2015 roku możesz po prostu użyć null, aby pominąć attr / prop. ie @include box-shadow($top, $left, $blur, $color, null)
— Upada

Odpowiedzi:


257

DRY'R Way to zrobić

I, ogólnie rzecz biorąc, fajna sztuczka, aby usunąć cytaty.

@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 wersja 3+, możesz użyć 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);
} 

Podniosłem to tutaj: przekaż listę do miksu jako pojedynczy argument z SASS


6
Jak zauważa Bob Sammers, w nowszej wersji SASS możesz również użyć metody unquote () zamiast # {}, aby usunąć cudzysłowy. Twoje zdrowie.
— Joshua Pinter

4
najprostszym sposobem jest użycie nulldomyślnej wartości parametrów opcjonalnych zamiast ""i nie będą one renderowane w wyniku! @mixin box-shadow($top, $left,... , $inset:null) {}
— S.Serpooshan,

@ S.Serpooshan Jestem ciekawy, w jakiej wersji został dodany. To z pewnością nie było obsługiwane w 2012 roku.
— Joshua Pinter

79

O wiele lepszy SUCHY sposób

ma przejść $args...do @mixin. W ten sposób, bez względu na to, ile $argszdasz. W @inputrozmowie możesz przekazać wszystkie potrzebne argumenty. Tak jak:

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

A teraz możesz ponownie użyć swojego cienia w każdej klasie, przekazując wszystkie potrzebne argumenty:

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

11
To dobrze wiedzieć, ale często razy jest to bardziej jasne wskazania co argumentami mixinspodziewa się, jak $top, $left, $bluritp Variable argumenty, jakbyś pokazano, świetnie nadają się do ostatecznego elastyczność, choć.
— Joshua Pinter

1
Dzięki, stary, bardzo mi to pomaga
— Nilesh Sutar,

48

Sass obsługuje @ifoświadczenia. (Zobacz dokumentację .)

Możesz napisać swój mixin w ten sposób:

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

Nie jest to tutaj przydatne, tylko insetczęść musi być wykluczona, gdy ma wartość NULL, nie wszystkie właściwości cienia
— S.Serpooshan,

@ S.Serpooshan Wystarczy dodać elsei dołączyć wszystkie nie wstawiane właściwości w środku.
— mbomb007,

@ mbomb007 Wiem, właśnie zgłosiłem problem z tym rozwiązaniem. Inne odpowiedzi podane powyżej są absolutnie lepsze.
— S.Serpooshan

26

Możesz ustawić właściwość z null jako wartość domyślną, a jeśli nie podasz parametru, nie zostanie on zinterpretowany.

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

Oznacza to, że możesz napisać instrukcję include w ten sposób.

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

Zamiast pisać w ten sposób.

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

Jak pokazano w odpowiedzi tutaj


1
Ta odpowiedź nie oferuje nic nowego w stosunku do istniejących odpowiedzi (patrz: stackoverflow.com/a/23565388/1652962 )
— cimmanon

9
@ cimmanon Wręcz przeciwnie, zapewnia to dodatkowe narzędzie, ponieważ można wtedy zapisać import @include box-shadow($top, $left, $blur, $color);zamiast @include box-shadow($top, $left, $blur, $color, null);. Dlatego ta odpowiedź jest o wiele bardziej korzystna.
— Dan

1
@ Dan W rzeczywistości tracisz czytelność, robiąc to w ten sposób, więc prawdopodobnie jest to mniej korzystne niż odpowiedź, z której pochodzi.
— TylerH,

@TylerH To prawda
— Dan

14

Stare pytanie, wiem, ale myślę, że to jest nadal aktualne. Prawdopodobnie wyraźniejszym sposobem na to jest użycie funkcji unquote () (którą SASS ma od wersji 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);
}

Jest to w przybliżeniu odpowiednik odpowiedzi Josha, ale myślę, że wyraźnie nazwana funkcja jest mniej zaciemniona niż składnia interpolacji łańcucha.


12

Wiem, że nie jest to dokładnie odpowiedź, "null"której @include box-shadowszukałeś, ale możesz podać jako ostatni argument podczas miksowania, tak jak @include box-shadow(12px, 14px, 2px, green, null);teraz Teraz, jeśli ten argument jest tylko jeden w tej właściwości niż ta właściwość (a jej (domyślna) wartość) nie zostanie skompilowana . Jeśli w tej „linii” znajdują się dwa lub więcej argumentów, tylko te, które zostały zerowane, nie zostaną skompilowane (twój przypadek).

Wyjście CSS jest dokładnie takie, jak chcesz, ale musisz napisać swoje null:)

  @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
Zdecydowanie mój ulubiony sposób na zrobienie tego sprawia, że ​​wszystko jest łatwe do odczytania i zrozumienia, kiedy trzeba wrócić do skryptu. dzięki Krople.
— Plentybinary

7

oto rozwiązanie, którego używam, z notatkami poniżej:

@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);
}
  • wolą przekazywać wartości właściwości jako natywne css, aby pozostać blisko „języka”
  • pozwalają na przekazywanie zmiennej liczby argumentów
  • zdefiniuj domyślną wartość lenistwa

Jak to coś dodaje do istniejących odpowiedzi (mianowicie: stackoverflow.com/a/28072864/1652962 )?
— cimmanon

Wyjaśnił, jak powiedzieć, czy do funkcji przekazywany jest więcej niż jeden argument, a jeśli tak, to należy zmienić wynik. Druga odpowiedź nie.
— TetraDev,

czasami chcesz zdefiniować zachowanie globalne. na przykład przejścia animacji, w których ogólnie chcesz mieć bardzo jednolite wrażenia i nie chcesz ryzykować „kreatywnego uznania twórcy”, jeśli chodzi o podejmowanie decyzji. definiuje to wartość domyślną, którą można zastąpić, ale często nie jest to spowodowane bardziej zwartą składnią, gdy nie przekazuje się argumentów. w ten sposób możesz także zmienić globalne zachowanie w jednym miejscu.
— duggi,

3

Z sass@3.4.9:

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

i użyj bez wartości, przycisk będzie niebieski

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

i wartości, przycisk będzie czerwony

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

działa również z hexa


Jak to coś dodaje do istniejących odpowiedzi?
— cimmanon

3

Nawet OSUSZANIE!

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

A teraz możesz ponownie wykorzystać swój cień-pudełko jeszcze mądrzej:

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

Tylko uwaga - jakkolwiek jest to czytelne i potwierdzam, że w tym miejscu należy wytyczyć granicę między kodem DRY a czytelnością / konserwacją .
— Leo Napoleon

Zgadzam się, aby zwiększyć czytelność / konserwację , stworzyłbym „listę przeglądarek” do ponownego użycia w innych miksach. Można to również dość łatwo połączyć z innymi właściwościami css, które można wykonać za pomocą zestawu suchych miksów. Ten artykuł z 2014 roku jest wciąż doskonałym przykładem.
— 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;
    }
}

Jest to prawdopodobnie gorsze niż wszystkie inne odpowiedzi, ze względu na jego gadatliwość. Ponadto jest wystarczająco blisko jednej z pozostałych odpowiedzi, aby uznać ją za duplikat.
— cimmanon,

1

Super prosty sposób

Wystarczy dodać wartość domyślną nonedo $ inset - więc

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

Teraz, gdy nie zostanie przekazana żadna wstawka $, nic nie będzie wyświetlane.


1

Zawsze możesz przypisać null swoim opcjonalnym argumentom. Oto prosta poprawka

@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

Jestem nowy w kompilatorach css, mam nadzieję, że to pomoże,

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

Jak to coś dodaje do istniejących odpowiedzi?
— cimmanon,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.