2014-07-11 10 views
6

Sto provando a raccogliere e comprendere il ragionamento dietro le convenzioni di denominazione CSS come BEM o SUITCss. Sto avendo difficoltà a capire il valore dei nomi di classi discendenti in presenza di SCSS.Qual è il punto della denominazione della classe discendente esplicita di BEM in presenza di SCSS?

Ad esempio:

<ul class="menu"> 
    <li class="menu__item"></li> 
    <li class="menu__item"></li> 
    <li class="menu__item"> 
     <a href="#" class="menu__item_link">link</a> 
    </li> 
</ul> 

.menu { 
    .menu__item { 
     //styles 
     .menu__item__link { //styles } 
    } 
    //or alternatively this syntax.. 
    &__item { //styles } 
} 

Con la possibilità di regole nido in SCSS, non vedo i motivi validi per me per includere i nomi delle classi antenato nel mio codice. Sopra ho definito gli stili che dovrebbero essere usati solo per un "oggetto" che si trova all'interno di un "menu", usando nomi di classi discendenti. Tuttavia, la struttura annidata già comunica questo! Le regole per menu__item si applicano solo a un elemento in un menu comunque, quindi perché è necessario includerlo nel nome della classe?

Perché non:

<ul class="menu"> 
    <li class="item"></li> 
</ul> 

.menu { 
    .item {//styles} 
} 

Capisco che la convenzione di denominazione discendente è più esplicito e forse più futuro amichevole. Io sostengo, tuttavia, che è solo più esplicito nell'html. Se volessi consultare come compilare questo modulo "menu", potrei semplicemente consultare il CSS e vedere chiaramente come all'interno di un menu sono presenti elementi.

immagino una possibile vantaggio è che ho potuto scrivere il mio css non-nested, in questo modo:

.menu { //styles } 
.menu__item { //styles } 
.menu__item__link { //styles } 

e quindi utilizzare un "menu__item" ovunque e sarebbe ancora essere esplicita nel nome della classe che questo era lo stile di un oggetto sotto un menu ... ma perché allora definirlo come un discendente di un menu? (Un altro vantaggio, suppongo, è stringhe di identificatori CSS più brevi se le cose non sono nidificate)

Mi sembra che se un nome di classe deve essere usato come discendente sotto un altro, allora l'annidamento in SCSS ottiene questo e presenta quella logica chiaramente. Perché questa sintassi BEM sarebbe necessaria allora?

Mi piacerebbe sentire qualcuno spiegare il ragionamento di questo tipo di convenzione. Voglio aderire alle cosiddette migliori pratiche, ma è difficile per me farlo in modo cieco senza dover comprendere una convenzione.

risposta

3

Iniziamo con l'idea di BEM o SMACSS.

Il compito principale che qualsiasi metodologia risolve è strutturare e modulare il codice.

Ad esempio uso BEM seguenti astrazioni:

Block - parte indipendente UI (come modulo di feedback),

Element - parte di blocco sopraelevazione esistere senza blocco (come tasto modulo di feedback) ,

Modificatore - helper che consente di modificare blocco o elemento (come il pulsante di creazione più grande o più piccolo).

SMACSS usa diverse astrazioni: modulo, layout, base, stato, tema. Per chiaramente avuto l'idea, immaginate la vostra pagina html contiene da strati di logica,

1) BASE - si aggiunge reset css, definire H1, H2 ...dimensioni dei caratteri, definizione dei colori. Quindi in base metti le cose di quelle che dovrebbero essere cambiate.

2) LAYOUT - aggiunge le griglie o pagina separata nelle regioni. 3) Modulo - elemento di contenuto indipendente

3) STATO - molto vicino alla BEM Modificatore ma connessa con una certa azione di modulo, come is_hided, is_collapsed

4) Tema - può essere usato per la forzatura BASE .

Quindi per separare queste astrazioni devi seguire alcune convenzioni di denominazione, in modo da poter capire dal primo sguardo cosa fa questa classe. Se segui la convenzione di denominazione, è anche molto più semplice mantenere il tuo progetto6 e spiegare facilmente ai nuovi membri del team come il codice è organizzato e come scrivere un nuovo codice che sembra scritto da una sola persona.

È estremamente importante in progetti su larga scala con team di grandi dimensioni.

Inoltre, la convenzione di denominazione consente di ridurre il numero di selettori discendenti, che migliorano le prestazioni.

+0

La convenzione di denominazione non ha alcun effetto sulle prestazioni a meno che non definisca i discendenti al di fuori del suo antenato, come nel mio ultimo esempio. Credo di capire l'argomento secondo cui qualcosa come BEM ti permette di "vedere a prima vista ciò che una classe fa/il suo contesto". Credo che la mia tesi sia che, con l'annidamento in SCSS, SCSS è altrettanto esplicito e chiaro. – Jeloi

+2

come ho detto dopo la convenzione di denominazione contribuirà a ridurre i discendenti, sì, come nel tuo ultimo esempio, sull'annidamento con SCSS, non sono sicuro che la sintassi sarà la stessa, ma in sass puoi usare e per costruire BEM o SMACSS come selettori - http : //stackoverflow.com/questions/24383308/sass-change-nested-elements-class-naming-style – Evgeniy

+0

Mi piace questa risposta di Evgeniy. Vorrei solo aggiungere che la convenzione di denominazione BEM impedisce le collisioni di denominazione in cui, ad esempio, due blocchi hanno un elemento denominato '.item'. Certo, puoi usare i selettori discendenti diretti per impedirlo, ma è più difficile refactoring il tuo markup perché qualsiasi piccolo cambiamento richiederà modifiche al CSS. –

7

Numerose osservazioni.

1/First,

.menu { 
    .menu__item { /* ... */ } 
    //or alternatively this syntax.. 
    &__item { /* ... */ } 
} 

I due sintassi SCSS non sono equivalenti. Il primo usa una cascata (".menu .menu__item"), non la seconda (".menu__item"). Solo il secondo è conforme a BEM.

2/Perché non una cascata:

.menu { 
    .item { /* styles */ } 
} 

BEM permette scalabilità. Quando scriviamo CSS, ci concentriamo solo su un piccolo contesto: il blocco. E ogni blocco può essere riutilizzato molte volte.

Ma le cascate non sono prive di contesto. Nel tuo esempio, c'è un "menu" di blocco che contiene un elemento "elemento". Il contesto dell'elemento "elemento" è il blocco "menu". Ma la cascata rompe la separazione del contesto per i sottoblocchi. Una sintassi BEM prefissata consente i blocchi di nidificazione, la cascata no. Ad esempio:

<ul class="menu"> 
    <li class="menu__item"></li> 
    <li class="menu__item"> 
     <div class="other-block"> 
      <span class="other-block__item"></span> 
     </div> 
    </li> 
</ul> 

Avviso l'elemento "elemento" nel sottoblocco. Con una cascata al posto di un prefisso, sarebbe designato da una regola che avrebbe come target gli elementi "elemento" del blocco genitore.

3/Questo nome classe non è compatibile BEM:

.menu__item__link { /* styles */ } 

elementi non forniscono alcun contesto. Solo i blocchi forniscono contesti. Il contesto di un elemento è il contesto del suo blocco. Quindi, "link" non è un discendente di "item" nell'albero BEM. I due sono fratelli, indipendentemente dalle loro situazioni nell'albero del DOM. Dovresti usare:

.menu { /* styles */ } 
.menu__item { /* styles */ } 
.menu__link { /* styles */ } 
Problemi correlati