2014-10-21 18 views
5

Mi piacerebbe implementare qualcosa come il modello BEM nella mia libreria Sass. Ma sto lottando per trovare un modo pulito per farlo.È possibile includere le proprietà principali in una classe Sass estesa?

Ad esempio, desidero dichiarare uno stile 'base' per un elemento comune, e quindi estendere con variazioni utili:

.container { 
    margin: 10%; 
    background: #eee; 

    &-featured { 
    border: 2px solid #999; 
    } 

} 

Il problema è che il generato .container-featured classe contiene un'unica proprietà border: Sass non include il margine e lo sfondo dalla sua classe 'padre'.

così si finisce per dover raddoppiare sulle classi nel vostro markup per ottenere i risultati desiderati:

<div class="container container-featured"> 
    ... 
</div> 

C'è qualche modo per tirare le proprietà di una classe genitore giù in quella classe modificatore, in modo da può ottenere lo stesso risultato visivo facendo semplicemente riferimento alla classe modificatore nel tuo markup?

<div class="container-featured"> 
    <!-- has margin, background, and border styles via just modifier class --> 
</div> 

Ho provato con mixins per fare questo, ma le cose si fanno verboso e ripetitivo molto rapidamente:

@mixins container { 
    margin: 10%; 
    background: #eee; 
} 

.container { 
    @include container; 

    &-featured { 
    @include container; 
    border: 2px solid #999; 
    } 

} 

C'è un modo semplice e pulita di raggiungere questo con Sass?

risposta

5

Quello che state cercando è la direttiva @extend. @extend consente di condividere un set di proprietà CSS da un selettore all'altro. Ciò significa che dovrai solo utilizzare la classe container-featured.

Esempio

.container { 
    margin: 10%; 
    background: #eee; 

    &-featured { 
    @extend .container; 
    border: 2px solid #999; 
    } 
} 

compila a:

.container, 
.container-featured { 
    margin: 10%; 
    background: #eee; 
} 

.container-featured { 
    border: 2px solid #999; 
} 
+0

È vero, e il codice CSS non sarà enorme. Modifico la mia risposta – Paleo

+0

Il CSS risultante non è quello che mi aspettavo, ma la soluzione rimane la stessa. Grazie mille, questo è abbastanza semplice da lavorare per me! – markedup

+1

Quindi, come si può fare riferimento a un selettore annidato? cioè 'container__item - mod' quando less is è scritto come' .container {& __ item {& - mod {}}} 'O c'è un modo migliore per nidificare? – Plummer

0

La soluzione Colin Bacon è la risposta corretta alla domanda. Ma per quanto riguarda la metodologia BEM, questo non è elegante. Ti suggerisco di usare un'altra sintassi BEM.

HTML:

<div class="Container featured"> 
    ... 
</div> 

SCSS:

.Container { 
    margin: 10%; 
    background: #eee; 

    &.featured { 
    border: 2px solid #999; 
    } 
} 

La sintassi:

  • ComponentName
  • ComponentName.modifierName
  • ComponentName-descendantNam e
  • ComponentName-descendantName.modifierName
  • ComponentName.isStateOfComponent
+0

mi piace questo approccio e, ma il concatenamento di classe in questo modo significa che alcuni browser meno recenti che devo ancora supportare non prenderanno in considerazione questi stili. – markedup

+1

Compatibile con IE7. Possiamo utilizzare questo selettore poiché Windows XP (IE6) non è più supportato. – Paleo

0

Si dovrebbe usare mixin in BEM non in Sass!

I mixaggi sono proprio questo: l'utilizzo di più blocchi e/o elementi sullo stesso nodo DOM.

Un singolo nodo DOM può rappresentare:

  • diversi isolati b-menu b-head-menu
  • un blocco e un elemento dello stesso blocco b-menu b-menu__layout
  • un blocco e un elemento di un altro blocco b-link b-menu__link
  • elementi di diversi blocchi b-menu__item b-head-menu__item
  • un blocco con un modificatore e un altro r bloccare b-menu b-menu_layout_horiz b-head-menu
  • diversi isolati differenti con modificatori b-menu b-menu_layout_horiz b-head-toolbar b-head-toolbar_theme_black

Maggiori informazioni si trovano: http://bem.github.io/bem-method/html/all.en.html, sezione Mixin.

Inoltre, è possibile utilizzare i-blocks (blocchi astratti), in modo che il contenitore .i sia .i-container, ulteriori informazioni: http://bem.github.io/bem-method/html/all.en.html, sezione Convenzioni di denominazione.

E con Sass è possibile implementare i-blocco come

<div class="container-featured"> 
    ... 
</div> 

%i-container { 
    // abstract block styles 
    margin: 10%; 
    background: #eee; 
} 

.container-featured { 
    @extend %i-container; 
    border: 2px solid #999; 
} 

Senza Sass, mixin nel BEM sono effettuati come segue:

<div class="i-container container-featured"> 
    ... 
</div> 

.i-container { 
    // abstract block styles 
    margin: 10%; 
    background: #eee; 
} 

.container-featured { 
    border: 2px solid #999; 
} 
+0

Oltre a rendere la dichiarazione di base del contenitore generico un segnaposto anziché una classe di antenati (che in realtà sembra una perdita di funzionalità in termini di comodità e riutilizzo), non capisco quali vantaggi questo approccio abbia rispetto al suggerimento di Colin? – markedup

+0

@markedup La differenza è che la proposta di Colin è solo un'eredità di stile. Ma il mio esempio è come farlo correttamente dal punto di vista della metodologia BEM - dal mixin. Per chiarire, ecco un esempio senza Sass:

.i-contenitore { // stili astratto blocco margine: 10%; background: #eee; } .container-featured { border: 2px solid # 999; } –