Erstellen eines Sass-Mixins mit optionalen Argumenten

201

Ich schreibe einen Mixin wie diesen:

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

Wenn ich aufgerufen werde, möchte ich wirklich, dass $insetnichts ausgegeben wird, wenn kein Wert übergeben wird, anstatt zu etwas wie diesem kompiliert zu werden:

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

Wie schreibe ich das Mixin so um, dass $insetnichts ausgegeben wird , wenn es keinen Wert für übergeben gibt?

Rich Bradshaw
quelle
6
Es ist eine Schande , dass SASS kein hat blankoder nilWert.
Joshua Pinter
1
Übrigens, als ich mir eine andere SASS-Einschränkung ansah, stieß ich auf eine gute Möglichkeit, die Anführungszeichen in diesen Situationen loszuwerden. Ich habe eine Antwort hinzugefügt.
Joshua Pinter
4
Jetzt im Jahr 2015 können Sie nur verwenden null, um attr / prop zu überspringen. ie @include box-shadow($top, $left, $blur, $color, null)
Drops

Antworten:

257

Eine trockene Art, es zu tun

Und im Allgemeinen ein guter Trick, um die Anführungszeichen zu entfernen.

@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+ können Sie verwenden 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);
} 

Habe das hier aufgegriffen: Übergebe eine Liste als einzelnes Argument mit SASS an ein Mixin

Joshua Pinter
quelle
6
Wie Bob Sammers betont, können Sie in einer neueren Version von SASS anstelle von # {} auch die Methode unquote () verwenden, um die Anführungszeichen zu entfernen. Prost.
Joshua Pinter
4
Am einfachsten ist es, nullanstelle von optionalen Parametern den Standardwert zu verwenden "", und diese werden in der Ausgabe nicht gerendert! @mixin box-shadow($top, $left,... , $inset:null) {}
Serpooshan
@ S.Serpooshan Ich bin gespannt, in welcher Version dies hinzugefügt wurde. Dies wurde sicherlich nicht im Jahr 2012 unterstützt.
Joshua Pinter
79

Ein viel besserer trockener Weg

ist an die $args...zu übergeben @mixin. Auf diese Weise, egal wie viele $argsSie passieren werden. Im @inputAufruf können Sie alle benötigten Argumente übergeben. Wie so:

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

Und jetzt können Sie Ihren Box-Shadow in jeder gewünschten Klasse wiederverwenden, indem Sie alle erforderlichen Argumente übergeben:

.my-box-shadow {
  @include box-shadow(2px 2px 5px #555, inset 0 0 0);
}
Fabricio
quelle
11
Das ist gut zu wissen , aber oft ist es mehr klar zu zeigen , was Argumente a mixinerwartet, wie $top, $left, $blurusw. Variable Argumente, wie Sie gezeigt haben, für ein Höchstmaß an Flexibilität groß sind, though.
Joshua Pinter
1
Danke, Alter, es hilft mir sehr
Nilesh Sutar
48

Sass unterstützt @ifAussagen. (Siehe Dokumentation .)

Sie könnten Ihr Mixin so schreiben:

@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;
  }
}
Andrew Vit
quelle
Dies ist hier nicht nützlich, nur das insetTeil muss ausgeschlossen werden, wenn es null ist, nicht alle Box-Shadow-Eigenschaften
S.Serpooshan
@ S.Serpooshan Fügen Sie einfach ein hinzu elseund fügen Sie alle nicht eingefügten Eigenschaften hinzu.
mbomb007
@ mbomb007 Ich weiß, ich melde gerade ein Problem mit dieser Lösung. Und andere Antworten oben sind absolut besser.
Serpooshan
26

Sie können die Eigenschaft mit null als Standardwert festlegen. Wenn Sie den Parameter nicht übergeben, wird er nicht interpretiert.

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

Dies bedeutet, dass Sie die include-Anweisung wie folgt schreiben können.

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

Anstatt es so zu schreiben.

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

Wie in der Antwort hier gezeigt

user1551211
quelle
1
Diese Antwort bietet nichts Neues über die vorhandenen Antworten (siehe: stackoverflow.com/a/23565388/1652962 )
Cimmanon
9
@cimmanon Im Gegenteil, dies bietet ein zusätzliches Dienstprogramm, da Sie den Import dann als @include box-shadow($top, $left, $blur, $color);statt schreiben können @include box-shadow($top, $left, $blur, $color, null);. Daher ist diese Antwort viel nützlicher.
Dan
1
@Dan Auf diese Weise verlieren Sie tatsächlich die Lesbarkeit, was wahrscheinlich weniger vorteilhaft ist als die Antwort, aus der es abgeleitet wurde.
TylerH
@ TylerH Das ist wahr
Dan
14

Alte Frage, ich weiß, aber ich denke, das ist immer noch relevant. Ein klarerer Weg, dies zu tun, ist wohl die Verwendung der Funktion unquote () (die SASS seit Version 3.0.0 hat):

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

Dies entspricht in etwa Joshs Antwort, aber ich denke, die explizit benannte Funktion ist weniger verschleiert als die Syntax der String-Interpolation.

Bob Sammers
quelle
12

Ich weiß, dass es nicht genau die Antwort ist, nach der Sie gesucht haben, aber Sie könnten "null"beim @include box-shadowMischen wie dieses als letztes Argument übergeben. @include box-shadow(12px, 14px, 2px, green, null);Wenn dieses Argument nur eines in dieser Eigenschaft ist, wird diese Eigenschaft (und ihr (Standard-) Wert) nicht kompiliert . Wenn sich in dieser "Zeile" zwei oder mehr Argumente befinden, werden nur diejenigen, die Sie auf Null gesetzt haben, nicht kompiliert (Ihr Fall).

Die CSS-Ausgabe ist genau so, wie Sie es wollten, aber Sie müssen Ihre nulls schreiben :)

  @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;
Tropfen
quelle
1
Auf jeden Fall ist es meine Lieblingsmethode, alles einfach zu lesen und zu verstehen, wenn Sie zu einem Skript zurückkehren müssen. Danke Tropfen.
Plentybinary
7

Hier ist die Lösung, die ich benutze, mit Anmerkungen unten:

@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);
}
  • Übergeben Sie lieber Eigenschaftswerte als native CSS, um in der Nähe von "der Zunge" zu bleiben.
  • Übergeben Sie eine variable Anzahl von Argumenten
  • Definieren Sie einen Standardwert für Faulheit
Duggi
quelle
Wie fügt dies etwas zu den vorhandenen Antworten hinzu (nämlich: stackoverflow.com/a/28072864/1652962 )?
Cimmanon
Er erklärte, wie man erkennt, ob mehr als ein Argument an die Funktion übergeben wird, und wenn ja, die Ausgabe ändert. Die andere Antwort tat es nicht.
TetraDev
Manchmal möchten Sie ein globales Verhalten definieren. Zum Beispiel Animationsübergänge, bei denen Sie im Allgemeinen eine sehr einheitliche Erfahrung machen möchten und bei der Entscheidung, was zu tun ist, nicht die "Diskretion kreativer Entwickler" riskieren möchten. Dies definiert einen Standard, der überschrieben werden kann, aber häufig nicht aufgrund der kompakteren Syntax, wenn keine Argumente übergeben werden. Auf diese Weise können Sie auch das globale Verhalten an einem einzigen Ort ändern.
Duggi
3

Mit [email protected]:

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

Bei Verwendung ohne Wert ist die Schaltfläche blau

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

und mit Wert wird die Schaltfläche rot angezeigt

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

funktioniert auch mit hexa

Gael
quelle
Wie fügt dies etwas zu den vorhandenen Antworten hinzu?
Cimmanon
3

Noch trockener!

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

Und jetzt können Sie Ihren Box-Shadow noch intelligenter wiederverwenden:

.myShadow {
  @include box-shadow(2px 2px 5px #555, inset 0 0 0);
}
Ben Kalsky
quelle
Nur eine Anmerkung - so lesbar dies auch ist und ich erkenne an, dass man hier die Grenze zwischen DRY-Code und Lesbarkeit / Wartbarkeit ziehen sollte .
Leo Napoleon
Ich stimme zu, um die Lesbarkeit / Wartbarkeit zu verbessern, würde ich eine "Browserliste" erstellen, die in anderen Mixins wiederverwendet werden kann. Dies könnte auch ziemlich einfach zu anderen CSS-Eigenschaften zusammengesetzt werden, die mit einem Satz trockener Mixins ausgeführt werden können. Dieser Artikel aus dem Jahr 2014 ist immer noch ein gutes Beispiel.
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;
    }
}
Adam C.
quelle
Dies ist aufgrund seiner Ausführlichkeit wohl schlimmer als alle anderen Antworten. Außerdem ist es nahe genug an einer der anderen Antworten, um als Duplikat zu gelten.
Cimmanon
1

Super einfacher Weg

Fügen Sie einfach einen Standardwert von none$ inset hinzu - also

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

Wenn jetzt kein $ inset übergeben wird, wird nichts angezeigt.

fidev
quelle
1

Sie können Ihren optionalen Argumenten jederzeit null zuweisen. Hier ist eine einfache Lösung

@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;
}
Benjamin
quelle
0

Ich bin neu in CSS-Compilern, hoffe das hilft,

        @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;
}
Mike Tracker
quelle
Wie fügt dies etwas zu den vorhandenen Antworten hinzu?
Cimmanon