Estensione dei selettori dalle media query con Sass


88

Ho una classe oggetto e una classe "modificatore" compatta:

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

Questo va bene. Tuttavia, vorrei aggiungere una @mediaquery che costringa la .itemclasse a essere compatta quando lo schermo è abbastanza piccolo.

A prima vista, questo è quello che ho provato a fare:

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

Ma questo genera il seguente errore:

Non puoi @extend un selettore esterno da @media. Puoi solo @extend selettori all'interno della stessa direttiva.

Come potrei farlo usando SASS senza dover ricorrere a stili di copia / incolla?


Cordiali saluti, ecco un problema che farebbe funzionare correttamente l'esempio che hai fornito: github.com/sass/sass/issues/1050
Ajedi32

Risposte:


118

La semplice risposta è: non puoi perché Sass non può (o non vuole) comporre il selettore per esso. Non puoi essere all'interno di una media query ed estendere qualcosa che è al di fuori di una media query. Sarebbe certamente bello se ne prendesse semplicemente una copia invece di provare a comporre i selettori. Ma non è così non puoi.

Usa un mixin

Se hai un caso in cui riutilizzerai un blocco di codice all'interno e all'esterno delle media query e desideri comunque che sia in grado di estenderlo, scrivi sia una classe mixin che una classe di estensione:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

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

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

Estendi il selettore dall'esterno all'interno di una media query

Questo non aiuterà molto il tuo caso d'uso, ma è un'altra opzione:

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

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

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

.bar {
  @extend %bar;
}

Attendi fino a quando Sass non solleva questa restrizione (o correggila tu stesso)

Sono in corso numerose discussioni riguardo a questo problema (per favore non contribuire a questi thread a meno che tu non abbia qualcosa di significativo da aggiungere: i manutentori sono già consapevoli che gli utenti desiderano questa funzionalità, è solo una questione di come implementarla e di cosa la sintassi dovrebbe essere).


@mindeavor Questo ha funzionato per te? Sei riuscito a utilizzare la classe estesa in una media query? In Sass 3.2?
Yahreen

1
%foonon è necessario, .foopuò direttamente @include foo.
phil294

Nel mio caso, ho appena usato il segnaposto% con estendere le query multimediali esterne. Quindi, all'interno della query multimediale, per il mio selettore ho appena aggiunto il segnaposto di estensione%. Vedrà se le discussioni arrivano con qualcosa di utile. Grazie Cimmanon.
keypaul

11

Per la cronaca, ecco come ho risolto il problema duplicando una sola volta gli stili generati:

// 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

Credo che SASS / SCSS non supporti la @extenddirettiva all'interno di una media query. http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

Potrebbe essere necessario utilizzare un mixin, anche se il volume del codice deve essere valutato rispetto al tuo obiettivo.


Un collegamento a una soluzione è il benvenuto, ma assicurati che la tua risposta sia utile senza di essa: aggiungi un contesto attorno al collegamento in modo che i tuoi colleghi utenti abbiano un'idea di cosa sia e perché sia ​​lì, quindi cita la parte più pertinente della pagina che tu " re collegamento a nel caso in cui la pagina di destinazione non è disponibile. Le risposte che sono poco più di un collegamento possono essere eliminate.
dippas

1

Questa è la soluzione più pulita e parziale che ho trovato. Sfrutta @extend ove possibile e ricade sui mixin quando si trovano all'interno di media query.

Direttive Cross-Media Query @extend in Sass

Vedi l'articolo per tutti i dettagli, ma il succo è che chiami un "segnaposto" di mixaggio che poi decide se produrre @extend o @include.

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

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

In definitiva, potrebbe non essere meglio che usare semplicemente i mixin, che è attualmente la risposta accettata.


0

Uso i punti di interruzione, ma è la stessa idea:

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

Come usarlo:

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

C'è un testo sui mixin dove puoi trovare maggiori informazioni su questa opzione.


-2

Potresti ristrutturare?

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

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

Se capisco correttamente la documentazione, dovrebbe funzionare. Penso che il motivo per cui stai provando non funzionerà è che non vede .item.compact quando analizza @extend, ma è un'ipotesi non informata, quindi prendila con un camion carico di sale! :)


Come stai compilando il tuo SASS? Esternamente, con JS o con un componente lato server di qualche tipo?
Jason M. Batchelor

Viene compilato tramite la rails-sassgemma standard , utilizzando SASS v3.2.4
soundly_typed

1
Sembra che la possibilità di estendere le query all'interno di @media sia deprecata e dovrebbe essere eliminata in 3.3: chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released (leggi l'area che dice "Limitazioni @extendnelle direttive CSS")
Jason M. Batchelor

Se ho capito correttamente queste informazioni, potrebbe essere quello che sta causando il problema. Sarei interessato a sapere cosa scoprirai!
Jason M. Batchelor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.