Memperluas pemilih dari dalam kueri media dengan Sass

88

Saya memiliki kelas item dan kelas "pengubah" yang ringkas:

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

Ini bagus. Namun, saya ingin menambahkan @mediakueri yang memaksa .itemkelas menjadi ringkas saat layarnya cukup kecil.

Pada pemikiran pertama, inilah yang saya coba lakukan:

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

Tetapi ini menghasilkan kesalahan berikut:

Anda tidak boleh @memperpanjang pemilih luar dari dalam @media. Anda hanya boleh @extend penyeleksi dalam arahan yang sama.

Bagaimana saya melakukannya dengan menggunakan SASS tanpa harus menggunakan gaya salin / tempel?

soundly_typed
sumber
Untuk diketahui, berikut adalah masalah yang akan membuat contoh yang Anda berikan berfungsi dengan benar: github.com/sass/sass/issues/1050
Ajedi32

Jawaban:

118

Jawaban sederhananya adalah: Anda tidak bisa karena Sass tidak bisa (atau tidak mau) menyusun pemilih untuk itu. Anda tidak bisa berada di dalam kueri media dan memperluas sesuatu di luar kueri media. Akan lebih baik jika itu hanya akan mengambil salinannya daripada mencoba membuat penyeleksi. Tapi tidak jadi Anda tidak bisa.

Gunakan campuran

Jika Anda memiliki kasus di mana Anda akan menggunakan kembali blok kode di dalam dan di luar kueri media dan masih ingin dapat memperpanjangnya, maka tulislah mixin dan kelas perluasan:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

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

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

Perluas pemilih dalam kueri media dari luar

Ini tidak akan membantu kasus penggunaan Anda, tetapi ini adalah opsi lain:

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

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

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

.bar {
  @extend %bar;
}

Tunggu sampai Sass mencabut batasan ini (atau tambal sendiri)

Ada sejumlah diskusi yang sedang berlangsung mengenai masalah ini (tolong jangan berkontribusi pada utas ini kecuali Anda memiliki sesuatu yang berarti untuk ditambahkan: pengelola sudah menyadari bahwa pengguna menginginkan fungsi ini, ini hanya pertanyaan tentang bagaimana menerapkannya dan apa sintaks harus).

cimmanon
sumber
@mindeavor Ini berhasil untuk Anda? Anda dapat menggunakan kelas yang diperluas dalam kueri media? Di Sass 3.2?
Yahreen
1
%footidak perlu, .foobisa langsung @include foo.
phil294
Untuk kasus saya, saya baru saja menggunakan% placeholder dengan perluasan kueri media luar. Kemudian, di dalam media query, untuk selektor saya baru saja menambahkan extensi% placeholder. Akan melihat apakah diskusi datang dengan sesuatu yang berguna. Terima kasih Cimmanon.
keypaul
11

Sebagai catatan, berikut adalah bagaimana saya akhirnya menyelesaikan masalah hanya dengan menduplikasi gaya yang dihasilkan sekali:

// 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;
  }
}
soundly_typed
sumber
2

Saya yakin SASS / SCSS tidak mendukung @extenddirektif di dalam kueri media. http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

Anda mungkin perlu menggunakan mixin, meskipun kode yang membengkak perlu dipertimbangkan terhadap tujuan Anda.

JHogue
sumber
Tautan ke solusi diperbolehkan, tetapi harap pastikan jawaban Anda berguna tanpanya: tambahkan konteks di sekitar tautan sehingga sesama pengguna Anda akan tahu apa itu dan mengapa itu ada, kemudian kutip bagian paling relevan dari halaman Anda ' menautkan ulang jika halaman target tidak tersedia. Jawaban yang tidak lebih dari sebuah tautan dapat dihapus.
dippas
1

Ini adalah solusi parsial terbersih yang saya temukan. Ini memanfaatkan @extend jika memungkinkan dan kembali ke mixin saat berada di dalam kueri media.

Kueri Lintas Media @extend Directive di Sass

Lihat artikel untuk detail lengkapnya tetapi intinya adalah Anda memanggil 'placeholder' mixin yang kemudian memutuskan apakah akan mengeluarkan @extend atau @include.

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

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

Pada akhirnya, ini mungkin tidak lebih baik daripada hanya menggunakan mixin, yang saat ini merupakan jawaban yang diterima.

Tom Genoni
sumber
0

Saya menggunakan breakpoint, tetapi idenya sama:

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

Bagaimana cara menggunakannya:

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

Ada teks tentang mixin tempat Anda dapat mengetahui lebih lanjut tentang opsi ini.

Nesha Zoric
sumber
-2

Bisakah Anda merestrukturisasi?

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

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

Jika saya memahami dokumentasi dengan benar, itu seharusnya berfungsi. Saya pikir alasan cara Anda mencoba tidak akan berhasil adalah karena ia tidak melihat .item.compact saat mengurai @extend, tapi itu tebakan yang kurang informasi, jadi ambillah dengan satu truk penuh garam! :)

Jason M. Batchelor
sumber
Bagaimana Anda menyusun SASS Anda? Secara eksternal, dengan JS, atau dengan semacam komponen sisi server?
Jason M. Batchelor
Ini sedang dikompilasi melalui rails-sasspermata standar , menggunakan SASS v3.2.4
soundly_typed
1
Sepertinya kemampuan untuk memperluas kueri @media sudah tidak digunakan lagi, dan akan dihapus di 3.3: chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released (baca area yang menyatakan "Batasan @extenddalam arahan CSS")
Jason M. Batchelor
Jika saya memahami informasi itu dengan benar, mungkin itulah penyebab masalahnya. Saya tertarik untuk mengetahui apa yang Anda temukan!
Jason M. Batchelor