การทำมิกซ์ Sass ด้วยอาร์กิวเมนต์ที่เป็นตัวเลือก


201

ฉันกำลังเขียนมิกซ์อินอย่างนี้:

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

เมื่อเรียกสิ่งที่ฉันต้องการจริงๆก็คือถ้าไม่มีการส่ง$insetค่าใด ๆจะไม่มีสิ่งใดส่งออกแทนที่จะรวบรวมสิ่งนี้:

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

ฉันจะเขียนมิกซ์อินใหม่เพื่อที่ว่าถ้าไม่มีค่าของการ$insetส่งผ่านจะไม่มีอะไรออก


6
มันเป็นความอัปยศที่ SASS ไม่มีblankหรือnilคุณค่า
Joshua Pinter

1
Btw ในขณะที่ดูข้อ จำกัด SASS ที่แตกต่างกันฉันได้พบวิธีที่ดีในการกำจัดคำพูดในสถานการณ์เหล่านี้ ฉันเพิ่มคำตอบสำหรับมัน
Joshua Pinter

4
ตอนนี้ในปี 2558 คุณสามารถใช้nullเพื่อข้าม attr / prop ie @include box-shadow($top, $left, $blur, $color, null)
Drops

คำตอบ:


257

วิธีที่จะทำให้มันแห้ง

และโดยทั่วไปแล้วเคล็ดลับที่เรียบร้อยในการลบเครื่องหมายคำพูด

@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 เวอร์ชัน 3+ คุณสามารถใช้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);
} 

เลือกสิ่งนี้ที่นี่: ส่งรายการไปยังมิกซ์อินเป็นอาร์กิวเมนต์เดี่ยวกับ SASS


6
ในขณะที่ Bob Sammers ชี้ให้เห็นใน SASS รุ่นใหม่กว่าคุณยังสามารถใช้เมธอด unquote () แทน # {} เพื่อลบเครื่องหมายคำพูด ไชโย
Joshua Pinter

4
วิธีที่ง่ายที่สุดคือการใช้nullสำหรับค่าเริ่มต้นของพารามิเตอร์ทางเลือกแทน""และพวกเขาจะไม่ถูกแสดงในการส่งออก! @mixin box-shadow($top, $left,... , $inset:null) {}
S.Serpooshan

@ S.Serpooshan ฉันอยากรู้ว่ารุ่นนี้ถูกเพิ่มเข้ามาอะไรแน่นอนว่ามันไม่ได้รับการสนับสนุนในปี 2012
Joshua Pinter

79

วิธีที่ดีกว่าแห้งมาก

คือการส่งผ่านไปยัง$args... @mixinด้วยวิธีนี้ไม่ว่า$argsคุณจะผ่านไปกี่คน ในการ@inputโทรคุณสามารถผ่าน args ทั้งหมดที่จำเป็น ชอบมาก

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

และตอนนี้คุณสามารถนำ box-shadow กลับมาใช้ใหม่ได้ในทุกชั้นเรียนที่คุณต้องการโดยผ่าน args ที่จำเป็นทั้งหมด:

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

11
ที่ดีที่จะรู้ แต่บ่อยครั้งก็เป็นที่ชัดเจนมากขึ้นในการระบุว่าข้อโต้แย้งmixinคาดว่าเช่น$top, $left, $blurฯลฯ ข้อโต้แย้งตัวแปรเหมือนคุณได้แสดงให้เห็นเป็นที่ดีสำหรับความยืดหยุ่นสูงสุดแม้ว่า
Joshua Pinter

1
ขอบคุณเพื่อนช่วยฉันมาก
Nilesh Sutar

48

Sass รองรับ@ifงบ (ดูเอกสารประกอบ )

คุณสามารถเขียนมิกซ์อินของคุณเช่นนี้:

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

สิ่งนี้ไม่มีประโยชน์ที่นี่insetจะต้องยกเว้นเฉพาะบางส่วนเมื่อมันเป็นโมฆะไม่ใช่คุณสมบัติเงาของกล่องทั้งหมด
S.Serpooshan

@ S.Serpooshan เพียงเพิ่มelseและรวมคุณสมบัติที่ไม่ใช่สิ่งที่ใส่เข้าไปภายใน
mbomb007

@ mbomb007 ฉันรู้ฉันแค่รายงานปัญหาด้วยวิธีนี้ และคำตอบอื่น ๆ ที่ให้ไว้ข้างต้นนั้นดีกว่าจริงๆ
S.Serpooshan

26

คุณสามารถใส่คุณสมบัติเป็นโมฆะเป็นค่าเริ่มต้นและถ้าคุณไม่ผ่านพารามิเตอร์มันจะไม่ถูกตีความ

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

หมายความว่าคุณสามารถเขียนคำสั่ง include เช่นนี้

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

แทนที่จะเขียนแบบนี้

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

ดังที่แสดงในคำตอบ ที่นี่


1
คำตอบนี้ไม่มีอะไรใหม่ในคำตอบที่มีอยู่ (ดู: stackoverflow.com/a/23565388/1652962 )
cimmanon

9
@cimmanon ในทางตรงกันข้ามนี้ให้ยูทิลิตี้เป็นพิเศษแล้วคุณสามารถเขียนนำเข้าเป็นแทน@include box-shadow($top, $left, $blur, $color); @include box-shadow($top, $left, $blur, $color, null);ดังนั้นคำตอบนี้เป็นประโยชน์อย่างมาก
ด่าน

1
@Dan ที่จริงแล้วคุณสูญเสียความสามารถในการอ่านด้วยวิธีการดังกล่าวดังนั้นจึงเป็นประโยชน์น้อยกว่าคำตอบที่ได้รับมา
TylerH

@TylerH นั่นคือความจริง
ด่าน

14

คำถามเก่าฉันรู้ แต่ฉันคิดว่านี่ยังเกี่ยวข้อง วิธีที่ชัดเจนในการทำเช่นนี้คือการใช้ฟังก์ชัน unquote () (ซึ่ง SASS มีมาตั้งแต่รุ่น 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);
}

นี่เทียบเท่ากับคำตอบของ Josh แต่ฉันคิดว่าฟังก์ชั่นที่ตั้งชื่ออย่างชัดเจนนั้นมีความสับสนน้อยกว่าไวยากรณ์การแก้ไขสตริง


12

ฉันรู้ว่ามันไม่ใช่คำตอบที่คุณต้องการ แต่คุณสามารถผ่าน"null"เป็นอาร์กิวเมนต์สุดท้ายเมื่อ@include box-shadowmixin เช่นนี้@include box-shadow(12px, 14px, 2px, green, null);หากอาร์กิวเมนต์นั้นเป็นเพียงหนึ่งในคุณสมบัตินั้นกว่าคุณสมบัตินั้น (และค่า (ค่าเริ่มต้น) จะไม่ถูกรวบรวม . หากมีสองหรือมากกว่า args ใน "บรรทัด" นั้นเท่านั้นที่คุณโมฆะจะไม่ได้รับการรวบรวม (กรณีของคุณ)

เอาท์พุท CSS ตรงตามที่คุณต้องการ แต่คุณต้องเขียน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
แน่นอนว่าวิธีที่ฉันชอบในการทำเช่นนี้ทำให้ทุกอย่างง่ายต่อการอ่านและทำความเข้าใจเมื่อคุณต้องกลับมาที่สคริปต์ ขอบคุณ
Plentybinary

7

นี่คือวิธีแก้ปัญหาที่ฉันใช้โดยมีหมายเหตุด้านล่าง:

@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);
}
  • ต้องการผ่านค่าคุณสมบัติเป็น css ดั้งเดิมเพื่ออยู่ใกล้กับ "ลิ้น"
  • อนุญาตให้ส่งผ่านจำนวนตัวแปรของข้อโต้แย้ง
  • กำหนดค่าเริ่มต้นสำหรับความเกียจคร้าน

สิ่งนี้เพิ่มอะไรมากกว่าคำตอบที่มีอยู่ (เช่น: stackoverflow.com/a/28072864/1652962 )
cimmanon

เขาอธิบายว่าจะบอกได้อย่างไรว่ามีมากกว่าหนึ่งอาร์กิวเมนต์ที่ถูกส่งผ่านไปยังฟังก์ชันและหากเป็นเช่นนั้นให้เปลี่ยนเอาต์พุต คำตอบอื่น ๆ ไม่ได้
TetraDev

บางครั้งคุณต้องการกำหนดพฤติกรรมระดับโลก ตัวอย่างเช่นการเปลี่ยนภาพเคลื่อนไหวที่โดยทั่วไปคุณต้องการมีประสบการณ์ที่เหมือนกันมากและไม่ต้องการเสี่ยง "ดุลยพินิจของนักพัฒนาสร้างสรรค์" เมื่อต้องตัดสินใจว่าจะทำอย่างไร สิ่งนี้จะกำหนดค่าเริ่มต้นที่สามารถเขียนทับได้ แต่มักจะไม่เกิดขึ้นเนื่องจากมีขนาดกะทัดรัดกว่าเมื่อไม่ผ่านการขัดแย้ง คุณสามารถเปลี่ยนพฤติกรรมทั่วโลกได้ในที่เดียวด้วยวิธีนี้
duggi

3

ด้วย sass@3.4.9:

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

และใช้โดยไม่มีค่าปุ่มจะเป็นสีน้ำเงิน

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

และด้วยค่าปุ่มจะเป็นสีแดง

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

ทำงานร่วมกับเฮกซ่าเกินไป


สิ่งนี้จะเพิ่มอะไรมากกว่าคำตอบที่มีอยู่?
cimmanon

3

แม้แต่วิธีที่แห้ง!

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

และตอนนี้คุณสามารถนำกล่องเงากลับมาใช้ใหม่ได้อย่างชาญฉลาดยิ่งขึ้น:

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

เพียงแค่ทราบ - ตามอ่านได้เช่นนี้เป็นและฉันจะรับทราบว่านี่คือที่หนึ่งควรจะวาดเส้นแบ่งระหว่างรหัสแห้งและการอ่าน / การบำรุงรักษา
Leo Napoleon

ฉันเห็นด้วยเพื่อเพิ่มความสามารถในการอ่าน / บำรุงรักษาฉันจะสร้าง "รายการเบราว์เซอร์" เพื่อนำมาใช้ในมิกซ์อินอื่น ๆ นี่อาจเป็นเรื่องง่ายที่จะรวมเข้ากับคุณสมบัติ css อื่น ๆ ที่สามารถดำเนินการได้ด้วยชุดมิกซ์อินแห้ง บทความนี้จากปี 2014 ยังคงเป็นตัวอย่างที่ดี
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;
    }
}

นี่คือเนื้อหาที่เลวร้ายยิ่งกว่าคำตอบอื่น ๆ ทั้งหมดเนื่องจากการใช้คำฟุ่มเฟื่อย นอกจากนี้ยังใกล้พอที่จะตอบหนึ่งในคำตอบอื่นให้ถือว่าซ้ำซ้อน
cimmanon

1

วิธีที่ง่ายสุด ๆ

เพียงเพิ่มค่าเริ่มต้นnoneเป็น $ inset

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

ตอนนี้เมื่อไม่มีการแทรก $ $ จะไม่มีการแสดงผลใด ๆ


1

คุณสามารถกำหนด null ให้กับอาร์กิวเมนต์ที่เลือกระบุได้เสมอ นี่คือการแก้ไขง่ายๆ

@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 หวังว่านี่จะช่วยได้

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

สิ่งนี้จะเพิ่มอะไรมากกว่าคำตอบที่มีอยู่?
cimmanon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.