Membuat Sass mixin dengan argumen opsional


201

Saya menulis mixin seperti ini:

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

Ketika dipanggil apa yang benar-benar saya inginkan adalah bahwa jika tidak ada $insetnilai yang diteruskan, tidak ada output, daripada kompilasi untuk sesuatu seperti ini:

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

Bagaimana cara menulis ulang mixin sehingga jika tidak ada nilai $inset lewat, tidak ada output?


6
Ini memalukan bahwa SASS tidak memiliki blankatau nilnilai.
Joshua Pinter

1
Btw, sambil melihat batasan SASS yang berbeda, saya menemukan cara yang bagus untuk menghilangkan tanda kutip dalam situasi ini. Saya menambahkan jawaban untuk itu.
Joshua Pinter

4
Sekarang pada tahun 2015 Anda hanya dapat menggunakan nulluntuk melewati attr / prop. ie @include box-shadow($top, $left, $blur, $color, null)
Turun

Jawaban:


257

Cara KERING untuk Melakukannya

Dan, umumnya, trik rapi untuk menghapus tanda kutip.

@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 Versi 3+, Anda dapat menggunakan 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);
} 

Ambil ini di sini: sampaikan daftar ke mixin sebagai argumen tunggal dengan SASS


6
Seperti yang ditunjukkan oleh Bob Sammers, dalam versi SASS yang lebih baru Anda juga dapat menggunakan metode tanda kutip () alih-alih # {} untuk menghapus tanda kutip. Bersulang.
Joshua Pinter

4
cara yang paling sederhana adalah menggunakan nullnilai default dari parameter opsional sebagai ganti "", dan mereka tidak akan ditampilkan dalam output! @mixin box-shadow($top, $left,... , $inset:null) {}
S.Serpooshan

@ S.Serpooshan Saya ingin tahu versi apa yang ditambahkan. Ini jelas tidak didukung pada tahun 2012.
Joshua Pinter

79

Cara KERING jauh lebih baik

adalah untuk lulus $args...ke @mixin. Dengan begitu, tidak peduli berapa banyak $argsyang akan Anda lewati. Dalam @inputpanggilan, Anda dapat melewati semua arg yang dibutuhkan. Seperti itu:

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

Dan sekarang Anda dapat menggunakan kembali bayangan kotak Anda di setiap kelas yang Anda inginkan dengan melewati semua argumen yang dibutuhkan:

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

11
Yang baik untuk mengetahui tetapi sering kali itu lebih jelas untuk menunjukkan argumen apa mixinmengharapkan, seperti $top, $left, $blur, dll argumen Variabel, seperti Anda telah menunjukkan, yang besar untuk fleksibilitas, meskipun.
Joshua Pinter

1
Terima kasih, Bung sangat membantu saya
Nilesh Sutar

48

Sass mendukung @ifpernyataan. (Lihat dokumentasi .)

Anda dapat menulis mixin Anda seperti ini:

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

Ini tidak berguna di sini, hanya insetbagian yang harus dikecualikan saat itu nol, tidak semua properti bayangan kotak
S.Serpooshan

@ S.Serpooshan Cukup tambahkan elsedan sertakan semua properti non-inset di dalamnya.
mbomb007

@ mbomb007 saya tahu, saya baru saja melaporkan masalah dengan solusi ini. Dan jawaban lain yang diberikan di atas benar-benar lebih baik.
S.Serpooshan

26

Anda dapat menempatkan properti dengan null sebagai nilai default dan jika Anda tidak melewati parameter itu tidak akan ditafsirkan.

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

Ini berarti Anda dapat menulis pernyataan sertakan seperti ini.

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

Alih-alih menulisnya seperti ini.

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

Seperti yang ditunjukkan pada jawaban di sini


1
Jawaban ini tidak menawarkan apa pun yang baru di atas jawaban yang ada (lihat: stackoverflow.com/a/23565388/1652962 )
cimmanon

9
@cimmanon Sebaliknya, ini menyediakan utilitas tambahan karena Anda dapat menulis impor sebagai @include box-shadow($top, $left, $blur, $color);gantinya @include box-shadow($top, $left, $blur, $color, null);. Karena itu jawaban ini jauh lebih buatan.
Dan

1
@Dan Sebenarnya Anda kehilangan keterbacaan karena melakukan hal itu, jadi bisa dibilang ini kurang menguntungkan daripada jawaban yang didapat.
TylerH

@ TylerH Itu benar
Dan

14

Pertanyaan lama, saya tahu, tapi saya pikir ini masih relevan. Arguably, cara yang lebih jelas untuk melakukan ini adalah dengan menggunakan fungsi tanda kutip () (yang sudah dimiliki SASS sejak versi 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);
}

Ini kira-kira setara dengan jawaban Josh, tapi saya pikir fungsi yang disebutkan secara eksplisit kurang dikaburkan dari sintaks interpolasi string.


12

Saya tahu ini bukan jawaban yang Anda cari tetapi Anda bisa memberikan "null"argumen terakhir ketika @include box-shadowmixin, seperti ini@include box-shadow(12px, 14px, 2px, green, null); Sekarang, jika argumen itu hanya satu di properti itu daripada properti itu (dan nilai (default)) tidak akan dikompilasi . Jika ada dua atau lebih argumen tentang "baris" itu, hanya argumen yang Anda batalkan tidak akan dikompilasi (kasing Anda).

Output CSS persis seperti yang Anda inginkan, tetapi Anda harus menulis 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
Jelas cara favorit saya untuk melakukan ini membuat semuanya mudah dibaca dan dimengerti ketika Anda harus kembali ke skrip. thnx Drops.
Plentybinary

7

di sini adalah solusi yang saya gunakan, dengan catatan di bawah ini:

@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);
}
  • lebih suka melewati nilai properti sebagai css asli untuk tetap dekat dengan "lidah"
  • memungkinkan lewat jumlah variabel argumen
  • tentukan nilai standar untuk kemalasan

Bagaimana ini menambahkan sesuatu di atas jawaban yang ada (yaitu: stackoverflow.com/a/28072864/1652962 )?
cimmanon

Dia menjelaskan bagaimana cara mengetahui jika lebih dari satu argumen dilewatkan ke fungsi dan jika demikian, ubah hasilnya. Jawaban lainnya tidak.
TetraDev

terkadang, Anda ingin mendefinisikan perilaku global. misalnya, transisi animasi di mana Anda biasanya ingin memiliki pengalaman yang sangat seragam dan tidak ingin mengambil risiko "kebijaksanaan pengembang kreatif" ketika harus memutuskan apa yang harus dilakukan. ini mendefinisikan default yang dapat ditimpa tetapi seringkali tidak akan karena sintaks yang lebih kompak ketika tidak melewati argumen. Anda juga dapat mengubah perilaku global di satu tempat dengan cara ini.
duggi

3

Dengan sass@3.4.9:

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

dan gunakan tanpa nilai, tombol akan berwarna biru

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

dan dengan nilai, tombol akan berwarna merah

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

bekerja dengan hexa juga


Bagaimana ini menambahkan sesuatu dari jawaban yang ada?
cimmanon

3

Bahkan cara KERING!

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

Dan sekarang Anda dapat menggunakan kembali bayangan kotak Anda lebih pintar:

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

Hanya sebuah catatan - dapat dibaca seperti ini dan saya mengakui bahwa, di sinilah orang harus menarik garis antara kode KERING dan keterbacaan / pemeliharaan .
Leo Napoleon

Saya setuju, untuk meningkatkan keterbacaan / pemeliharaan, saya akan membuat "daftar browser" untuk digunakan kembali dalam mixin lainnya. Ini juga bisa dengan mudah dirakit ke properti css lainnya, yang dapat dieksekusi dengan satu set mixin kering. Artikel dari tahun 2014 ini masih merupakan contoh yang bagus.
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;
    }
}

Ini bisa dibilang lebih buruk daripada semua jawaban lain, karena verbositasnya. Juga, cukup dekat dengan salah satu jawaban lain untuk dihitung sebagai duplikat.
cimmanon

1

Cara super sederhana

Tambahkan saja nilai default noneke $ inset - so

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

Sekarang ketika $ inset dilewatkan, tidak ada yang akan ditampilkan.


1

Anda selalu dapat menetapkan nol untuk argumen opsional Anda. Ini adalah perbaikan sederhana

@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

Saya baru mengenal kompiler css, semoga ini membantu,

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

Bagaimana ini menambahkan sesuatu dari jawaban yang ada?
cimmanon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.