Rozszerzanie selektorów z zapytań o media za pomocą Sass

86

Mam klasę pozycji i kompaktową klasę „modyfikatora”:

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

Jest okej. Chciałbym jednak dodać @mediazapytanie, które wymusza .itemzwartość klasy, gdy ekran jest wystarczająco mały.

Na początku starałem się to zrobić:

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

Ale to generuje następujący błąd:

Nie możesz @extend zewnętrznego selektora z poziomu @media. Możesz tylko @extend selektory w ramach tej samej dyrektywy.

Jak mógłbym to osiągnąć za pomocą SASS bez konieczności kopiowania / wklejania stylów?

soundly_typed
źródło
Fyi, oto problem, który sprawiłby, że podany
Ajedi32

Odpowiedzi:

112

Prosta odpowiedź brzmi: nie możesz, ponieważ Sass nie może (lub nie chce) skomponować dla niego selektora. Nie możesz znajdować się wewnątrz zapytania o media i rozszerzać czegoś, co jest poza zapytaniem o media. Z pewnością byłoby miło, gdyby po prostu skopiował to, zamiast próbować skomponować selektory. Ale tak nie jest, więc nie możesz.

Użyj miksera

Jeśli masz przypadek, w którym zamierzasz ponownie wykorzystać blok kodu wewnątrz i na zewnątrz zapytań o media i nadal chcesz, aby mógł go rozszerzyć, napisz zarówno klasę mixin, jak i rozszerzoną:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

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

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

Rozszerz selektor w zapytaniu o media z zewnątrz

To naprawdę nie pomoże w przypadku użycia, ale jest to inna opcja:

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

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

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

.bar {
  @extend %bar;
}

Poczekaj, aż Sass zniesie to ograniczenie (lub załataj je samodzielnie)

Trwa wiele dyskusji dotyczących tego problemu (proszę nie wnosić udziału w tych wątkach, chyba że masz coś sensownego do dodania: opiekunowie są już świadomi, że użytkownicy chcą tej funkcji, to tylko kwestia tego, jak ją wdrożyć i co składnia powinna być).

cimmanon
źródło
@mindeavor To działało dla Ciebie? Udało Ci się użyć rozszerzonej klasy w zapytaniu o media? W Sass 3.2?
Yahreen
1
%foojest niepotrzebne, .foomoże bezpośrednio @include foo.
phil294,
W moim przypadku właśnie użyłem symbolu zastępczego% z rozszerzeniem poza zapytaniami o media. Następnie, w zapytaniu o media, dla mojego selektora dodałem tylko symbol zastępczy rozszerzenia%. Zobaczy, czy do dyskusji przyda się coś przydatnego. Dzięki Cimmanon.
keypaul
11

Dla przypomnienia, oto jak skończyłem, rozwiązując problem, powielając tylko raz wygenerowane style:

// 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
źródło
2

Uważam, że SASS / SCSS nie obsługuje @extenddyrektywy w zapytaniu o media. http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

Być może będziesz musiał użyć zamiast tego mixinu, chociaż nadmiar kodu musi być zważony w stosunku do celu.

JHogue
źródło
Link do rozwiązania jest mile widziany, ale upewnij się, że Twoja odpowiedź jest przydatna bez niego: dodaj kontekst wokół linku, aby inni użytkownicy mieli pojęcie, co to jest i dlaczego się tam znajduje, a następnie zacytuj najbardziej odpowiednią część strony, którą podałeś. ponowne łącze w przypadku, gdy strona docelowa jest niedostępna. Odpowiedzi, które są niewiele więcej niż linkiem, mogą zostać usunięte.
dippas
1

To najczystsze, częściowe rozwiązanie, jakie znalazłem. Tam, gdzie to możliwe, korzysta z @extend i wraca do mixinów w zapytaniach o media.

Dyrektywy zapytania cross-media @extend w Sass

Zobacz artykuł, aby uzyskać szczegółowe informacje, ale sednem jest to, że wywołujesz `` symbol zastępczy '' mieszania, który następnie decyduje, czy wypisać @extend, czy @include.

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

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

Ostatecznie może nie być lepsze niż zwykłe użycie mixinów, co jest obecnie akceptowaną odpowiedzią.

Tom Genoni
źródło
0

Używam punktów przerwania, ale to ten sam pomysł:

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

Jak tego użyć:

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

Jest tekst o mieszankach, w którym możesz dowiedzieć się więcej o tej opcji.

Nesha Zoric
źródło
-2

Czy mógłbyś przeprowadzić restrukturyzację?

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

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

Jeśli dobrze zrozumiem dokumentację, powinno działać. Myślę, że powodem, dla którego próbujesz nie zadziałać, jest to, że nie widzi .item.compact podczas analizowania @extend, ale to niedoinformowany przypuszczenie, więc weź to z ciężarówką pełną soli! :)

Jason M. Batchelor
źródło
Jak kompilujesz SASS? Zewnętrznie, za pomocą JS lub jakiegoś komponentu po stronie serwera?
Jason M. Batchelor,
Jest kompilowany za pomocą standardowego rails-sassklejnotu, przy użyciu SASS v3.2.4
soundly_typed
1
Wygląda na to, że możliwość rozszerzania wewnątrz zapytań @media jest przestarzała i ma zostać ograniczona w wersji 3.3: chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released (przeczytaj obszar, w którym jest napisane „Ograniczenia @extendw dyrektywach CSS”)
Jason M. Batchelor,
Jeśli dobrze zrozumiałem te informacje, może to być przyczyną problemu. Chciałbym wiedzieć, czego się dowiedziałeś!
Jason M. Batchelor,