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?


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


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

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

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


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.


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;

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

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 sass@3.4.9:

// 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


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

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

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.


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

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

Wie fügt dies etwas zu den vorhandenen Antworten hinzu?
Cimmanon
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.