การขยายตัวเลือกจากภายในแบบสอบถามสื่อด้วย Sass


88

ฉันมีคลาสไอเท็มและคลาส "ตัวปรับแต่ง" ขนาดกะทัดรัด:

.item { ... }
.item.compact { /* styles to make .item smaller */ }

แค่นี้ก็เรียบร้อย อย่างไรก็ตามฉันต้องการเพิ่ม@mediaคำค้นหาที่บังคับให้.itemชั้นเรียนมีขนาดกะทัดรัดเมื่อหน้าจอมีขนาดเล็กพอ

ในความคิดแรกนี่คือสิ่งที่ฉันพยายามทำ:

.item { ... }
.item.compact { ... }
@media (max-width: 600px) {
  .item { @extend .item.compact; }
}

แต่สิ่งนี้ทำให้เกิดข้อผิดพลาดต่อไปนี้:

คุณไม่สามารถ @ ขยายตัวเลือกภายนอกจากภายใน @media คุณสามารถเลือก @extend ได้เฉพาะในคำสั่งเดียวกันเท่านั้น

ฉันจะทำสิ่งนี้ให้สำเร็จโดยใช้ SASS โดยไม่ต้องหันไปคัดลอก / วางสไตล์ได้อย่างไร


Fyi นี่คือปัญหาที่จะทำให้ตัวอย่างที่คุณให้มาทำงานได้อย่างถูกต้อง: github.com/sass/sass/issues/1050
Ajedi32

คำตอบ:


118

คำตอบง่ายๆคือคุณทำไม่ได้เพราะ Sass ไม่สามารถ (หรือไม่) เขียนตัวเลือกสำหรับมัน คุณไม่สามารถอยู่ในแบบสอบถามสื่อและขยายสิ่งที่อยู่นอกแบบสอบถามสื่อได้ คงจะดีแน่นอนถ้าเพียงแค่ใช้สำเนาแทนที่จะพยายามเขียนตัวเลือก แต่มันไม่เป็นเช่นนั้นคุณทำไม่ได้

ใช้ mixin

หากคุณมีกรณีที่คุณจะนำบล็อกโค้ดกลับมาใช้ใหม่ทั้งภายในและภายนอกคิวรีสื่อและยังต้องการให้สามารถขยายได้ให้เขียนทั้งมิกซ์อินและคลาสขยาย:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

// usage
.foo {
    @extend %foo;
}

@media (min-width: 30em) {
    .bar {
        @include foo;
    }
}

ขยายตัวเลือกภายในแบบสอบถามสื่อจากภายนอก

สิ่งนี้จะไม่ช่วยกรณีการใช้งานของคุณ แต่เป็นอีกทางเลือกหนึ่ง:

%foo {
  @media (min-width: 20em) {
    color: red;
  }
}

@media (min-width: 30em) {
  %bar {
    background: yellow;
  }
}

// usage
.foo {
  @extend %foo;
}

.bar {
  @extend %bar;
}

รอจนกว่า Sass จะยกเลิกข้อ จำกัด นี้ (หรือแก้ไขด้วยตัวเอง)

มีการอภิปรายอย่างต่อเนื่องเกี่ยวกับปัญหานี้ (โปรดอย่ามีส่วนร่วมในเธรดเหล่านี้เว้นแต่คุณจะมีบางสิ่งที่มีความหมายที่จะเพิ่ม: ผู้ดูแลทราบอยู่แล้วว่าผู้ใช้ต้องการฟังก์ชันนี้เป็นเพียงคำถามเกี่ยวกับวิธีการใช้งานและสิ่งที่ ไวยากรณ์ควรเป็น)


@mindeavor นี้ได้ผลสำหรับคุณ? คุณสามารถใช้คลาสเพิ่มเติมในแบบสอบถามสื่อ? ใน Sass 3.2?
Yahreen

1
%fooไม่จำเป็นสามารถโดยตรง.foo @include foo
phil294

สำหรับกรณีของฉันฉันเพิ่งใช้% ตัวยึดตำแหน่งกับการขยายแบบสอบถามสื่อภายนอก จากนั้นภายในแบบสอบถามสื่อสำหรับตัวเลือกของฉันเพิ่งเพิ่มตัวยึดตำแหน่งขยาย% จะดูว่าการอภิปรายมาพร้อมกับสิ่งที่สะดวกหรือไม่ ขอบคุณ Cimmanon
keypaul

11

สำหรับบันทึกนี่คือวิธีที่ฉันลงเอยด้วยการแก้ปัญหาโดยทำซ้ำรูปแบบที่สร้างขึ้นเพียงครั้งเดียว:

// This is where the actual compact styles live
@mixin compact-mixin { /* ... */ }

// Include the compact mixin for items that are always compact
.item.compact { @include compact-mixin; }

// Here's the tricky part, due to how SASS handles extending
.item { ... }
// The following needs to be declared AFTER .item, else it'll
// be overridden by .item's NORMAL styles.
@media (max-width: 600px) {
  %compact { @include compact-mixin; }

  // Afterwards we can extend and
  // customize different item compact styles
  .item {
    @extend %compact;
    /* Other styles that override %compact */
  }
  // As shown below, we can extend the compact styles as many
  // times as we want without needing to re-extend
  // the compact mixin, thus avoiding generating duplicate css
  .item-alt {
    @extend %compact;
  }
}

2

ฉันเชื่อว่า SASS / SCSS ไม่รองรับ@extendคำสั่งภายในแบบสอบถามสื่อ http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

คุณอาจต้องใช้ mixin แทนแม้ว่า code bloat จะต้องได้รับการชั่งน้ำหนักตามวัตถุประสงค์ของคุณ


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

1

นี่เป็นวิธีแก้ปัญหาบางส่วนที่สะอาดที่สุดที่ฉันพบ ใช้ประโยชน์จาก @extend เมื่อเป็นไปได้และถอยกลับไปที่ mixins เมื่ออยู่ในแบบสอบถามของสื่อ

Cross-Media Query @extend Directives ใน Sass

ดูบทความเพื่อดูรายละเอียดทั้งหมด แต่ส่วนสำคัญคือคุณเรียกตัวยึด mixin 'ซึ่งจะตัดสินใจว่าจะส่งออก @extend หรือ @include

@include placeholder('clear') {
   clear: both;
   overflow: hidden;
}

.a {
    @include _(clear);
}
.b {
    @include _(clear);
}
.c {
    @include breakpoint(medium) {
      @include _(clear);
   }
}

ท้ายที่สุดแล้วอาจไม่ดีไปกว่าการใช้มิกซ์อินซึ่งเป็นคำตอบที่ยอมรับได้ในปัจจุบัน


0

ฉันใช้เบรกพอยต์ แต่ก็เป็นแนวคิดเดียวกัน:

@mixin bp-small {
    @media only screen and (max-width: 30em) {
        @content;
    }

วิธีใช้:

.sidebar {
    width: 60%;
    float: left;
    @include bp-small {
        width: 100%;
        float: none;
    }
}

มีข้อความเกี่ยวกับมิกซ์อินที่คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกนี้ได้


-2

คุณช่วยปรับโครงสร้างได้ไหม

.compact { //compact-styles }
.item {}
.item.compact { @extend .compact } 

@media (max-width: 600px) {
    .item { @extend .compact; }
}

ถ้าฉันเข้าใจเอกสารอย่างถูกต้องก็น่าจะใช้ได้ ฉันคิดว่าเหตุผลที่คุณพยายามจะไม่ได้ผลคือมันไม่เห็น. item.compact เมื่อแยกวิเคราะห์ @extend แต่นั่นเป็นการเดาที่ไม่รู้ดังนั้นจงใช้มันด้วยการบรรทุกเกลือ! :)


คุณรวบรวม SASS ของคุณอย่างไร? ภายนอกด้วย JS หรือด้วยส่วนประกอบฝั่งเซิร์ฟเวอร์ในบางประเภท?
Jason M. Batchelor

มันถูกรวบรวมผ่านrails-sassอัญมณีมาตรฐานโดยใช้ SASS v3.2.4
soundly_typed

1
ดูเหมือนว่าความสามารถในการขยายภายในแบบสอบถาม @media จะเลิกใช้แล้วและเนื่องจากถูกแกนใน 3.3: chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released (อ่านพื้นที่ที่ระบุว่า "ข้อ จำกัด@extendในคำสั่ง CSS")
Jason M. Batchelor

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