Introduzione alla metodologia BEM

Pubblicato: 2022-03-11

Che cos'è la metodologia BEM?

Quando crei siti Web più piccoli, il modo in cui organizzi i tuoi stili di solito non è un grosso problema. Crei i tuoi soliti file, scrivi tutti i CSS necessari e questo è tutto. Tuttavia, quando si tratta di progetti più grandi e complessi, il modo in cui organizzi il tuo codice diventa cruciale . Il modo in cui è strutturato il codice è ancora più importante se si lavora in un team composto da più sviluppatori front-end e back-end.

La metodologia BEM migliorerà enormemente la manutenibilità del codice e accelererà il processo di sviluppo

La metodologia BEM migliorerà enormemente la manutenibilità del codice e accelererà il processo di sviluppo
Twitta

Oggi ci sono molte metodologie con l'obiettivo di ridurre il codice CSS e rendere il tuo codice CSS più manutenibile. In questo articolo, spiegherò e fornirò alcuni esempi di uno di essi: BEM. BEM sta per B lock E lement Modifier. L'idea principale alla base è accelerare il processo di sviluppo e facilitare il lavoro di squadra degli sviluppatori organizzando le classi CSS in moduli indipendenti. Se hai mai visto un nome di classe come header__form--search , è BEM in azione. Sì, le classi possono essere nominate molto lunghe, ma sono tutte leggibili e comprensibili.

Tieni presente che la procedura consigliata consiste nell'utilizzare BEM solo con le classi e non con gli ID perché le classi consentono di ripetere i nomi se necessario e creare una struttura di codifica più coerente. Inoltre, se desideri suddividere il tuo sito Web in moduli organizzati, dovrebbe essere costituito dalla stessa struttura: blocco, elemento e modificatore. Dove ogni blocco può avere più elementi e sia il blocco che gli elementi possono avere più modificatori. Tuttavia, iniziamo prima con la struttura BEM di base e la spieghiamo con esempi.

Bloccare

Un blocco rappresenta un oggetto nel tuo sito web. Pensalo come pezzi strutturali più grandi del tuo codice. I blocchi più comuni su ogni sito Web oggi sono intestazione, contenuto, barra laterale, piè di pagina e ricerca. I blocchi in BEM sono sempre un punto di partenza per concatenare le tue classi CSS. Dai un'occhiata ad alcuni esempi di blocchi:

  • un contenuto
  • un menù
  • un modulo di ricerca
 .content {/* Styles */} .menu {/* Styles */} .search {/* Styles */}

Elemento

Un elemento è un componente all'interno del blocco che svolge una particolare funzione. Dovrebbe avere senso solo nel contesto del suo blocco:

  • un articolo di contenuto
  • una voce di menu
  • un campo di immissione di ricerca
 .content__article {/* Styles */} .menu__item {/* Styles */} .search__input {/* Styles */}

Modificatore

Un modificatore è il modo in cui rappresentiamo le variazioni di un blocco. Se hai mai usato Bootstrap, il miglior esempio sarebbero le dimensioni dei pulsanti. Le dimensioni dei pulsanti sono solo variazioni delle dimensioni del pulsante stesso, il che lo rende il modificatore:

  • un articolo in primo piano
  • un collegamento di menu
  • un campo di ricerca con o senza icona
 .content__article--featured {/* Styles */} .menu__item--link {/* Styles */} .search__input--icon {/* Styles */}

Convenzioni di denominazione

Lo scopo principale della metodologia BEM è rendere i nomi dei selettori CSS il più informativi e trasparenti possibile. Lo stile BEM originale è definito in questo modo:

Il nome del blocco è solitamente una singola parola come .header , ma se hai una definizione del blocco più lunga, viene divisa con un singolo trattino - :

 .lang-switcher {/* Styles */}

Il nome dell'elemento inizia con un doppio trattino basso __ :

 .lang-switcher__flag {/* Styles */}

Il nome del modificatore inizia con un singolo trattino basso _ :

 .lang-switcher__flag_basic {/* Styles */}

C'è solo una regola molto critica nella metodologia BEM: un modificatore non può essere utilizzato al di fuori del contesto del suo proprietario.

Esempio:

 .btn_big {/* Styles */}

Puoi usare btn_big solo se anche l'intestazione è definita.

Cattivo esempio:

 <div class=”btn_big”>...</div>

Buon esempio:

 <div class=”btn btn_big”>...</div>

Oltre a questi stili BEM originali, esistono schemi di denominazione alternativi come gli stili Harry Roberts e CamelCase.

Esempio di stile di Harry Roberts:

 .block-name__element-name--modifier-name {/* Styles */}

Esempio di stile CamelCase:

 .BlockName__ElementName_ModifierName {/* Styles */}

Ce ne sono anche pochi altri, ma questi due sono i più comuni. Personalmente, sono un fan della convenzione di denominazione proposta da Harris Roberts, che prevede le seguenti regole:

  • I nomi sono scritti in minuscolo
  • Le parole all'interno dei nomi delle entità BEM sono separate da un trattino -
  • Il nome di un elemento è separato dal nome di un blocco da un doppio trattino basso __
  • I modificatori booleani sono delimitati da doppi trattini --
  • I modificatori di tipo valore-chiave non vengono utilizzati

Il motivo per cui questa convenzione di denominazione è formata molto meglio di altre è che puoi facilmente distinguere l'elemento modificatore dagli altri. Nelle convenzioni di denominazione originali, il modificatore sarebbe definito in questo modo:

 .block__element_modifier {/* Styles */}

Ma come puoi vedere, non c'è molta differenza tra un singolo e un doppio underscore. D'altra parte, il doppio trattino fornisce una separazione netta e puoi vedere immediatamente il modificatore:

 .block__element--modifier {/* Styles */}

Esempio BEM in diversi formati

Tieni presente che oltre a CSS, BEM è anche molto utile per organizzare i tuoi file JSON, XML, albero o qualsiasi formato che supporta la nidificazione. Pensa alla metodologia BEM come un buon modo per costruire la tua interfaccia utente.

HTML strutturato in formato BEM

Consideriamo il seguente HTML, strutturato in formato BEM:

 <header class=”header”> <img class=”header__logo”> <form class=”header__search-from”> <input class=”header__search-from__input” type=”input”> <button class=”header__search-from__button” type=”button”> </form> <div class=”header__lang-switcher”></div> </header>

Lo stesso può essere ottenuto utilizzando il formato JSON e XML.

XML:

 <block:header> <block:logo/> <block:search-from> <block:input/> <block:button/> </block> <block:lang-switcher/> </block>

JSON:

 { block: 'header', content: [ { block: 'logo' }, { block: 'search-form', content: [ { block: 'input' }, { block: 'button' } ] }, { block: 'lang-switcher' } ] }

Organizzazione del file system di un progetto BEM

In BEM, è fondamentale organizzare i file in modo corretto. BEM non solo ti fornisce un'ottima organizzazione delle classi CSS e le rende completamente comprensibili, ma ti offre anche una struttura di file molto manutenibile. Prendiamo un progetto di esempio, utilizzando la tecnica di organizzazione dei file BEM con i file SASS:

 blocks/ input/ __box/ --big/ input__box--big.scss input__box.scss button/ --big/ button--big.scss

Come puoi vedere sopra, solo vedendo la struttura delle sottocartelle all'interno della tua cartella principale, tutto è chiaro e organizzato. In questo modo, non fa differenza chi sta lavorando dopo di te o se stai lavorando dopo qualcuno, perché è incredibilmente facile seguire lo stesso schema.

Dividere il progetto BEM in piattaforme

Oltre a organizzare i tuoi file utilizzando le tecniche della metodologia BEM, puoi anche approfondire cose più specifiche. Ad esempio, se stai creando un progetto Web che sarà completamente reattivo e il client ha specificato che alcuni blocchi sul dispositivo mobile sono completamente diversi da quelli sui dispositivi desktop, sarebbe meglio dividere la struttura delle cartelle BEM in piattaforme. Esempio di organizzazione dei pulsanti su varie piattaforme:

 common.blocks/ button/ button.scss desktop.blocks/ button/ buttons.scss mobile.blocks/ button/ button.scss

Nota che questo è solo un esempio se desideri organizzare l'intero progetto utilizzando la metodologia BEM. L'albero dei file con struttura BEM non è obbligatorio per utilizzare BEM correttamente, puoi utilizzare BEM solo in alcuni segmenti del progetto. Finora non ho utilizzato questa rigida organizzazione della struttura dei file BEM in cui ogni elemento e modificatore ha il proprio file creato. Invece, sto solo creando una struttura di file per i blocchi che hanno una dichiarazione dei suoi elementi e modificatori.

Organizzazione ad albero di un progetto BEM

BEM in pratica

Poiché ora hai familiarità con le convenzioni di denominazione, dimostrerò in pratica la metodologia BEM. Diciamo che abbiamo questo codice HTML in azione:

 <a class=”btn btn--big btn--primary-color” href=”#” title=”Title”> <span class=”btn__price”>$3.99</span> <span class=”btn__text”>Product</span> </a>

Con il seguente markup CSS applicato:

 .btn__price {/* Styles */} .btn__text {/* Styles */} .btn--big {/* Styles */} .btn--primary-color {/* Styles */}

Ora, non essere fuorviato. Nei nostri esempi finora abbiamo quasi sempre avuto un blocco, un elemento e un modificatore, il che non deve essere sempre il caso.

Ad esempio, supponiamo di avere un blocco denominato person . Una persona ha gambe e mani, può anche essere femmina o maschio. Se vogliamo definire una persona di sesso maschile con la mano destra apparirà così:

 .person--male__hand--right {/* Styles */}

Ora puoi vedere il vero significato del BEM. Abbiamo definito una persona il cui modificatore è un genere. Dal momento che non importa se una persona è maschio o femmina, ha una mano e la mano è un elemento. E ancora, ogni persona può avere la mano destra o sinistra che è di nuovo un modificatore.

In un altro caso, se vogliamo definire una persona generica con una sola mano, lo faremo in questo modo:

 .person__hand {/* Styles */}

Come puoi notare, una volta che ti senti a tuo agio con BEM, è molto facile strutturare la tua struttura CSS e HTML con esso.

Utilizzo di BEM con preprocessori CSS

Personalmente, non riesco a immaginare di iniziare un nuovo progetto senza utilizzare uno dei preprocessori CSS. Come tutti sapete, i preprocessori sono un'ottima cosa e ci stanno fornendo molti vantaggi e, soprattutto, sono una combinazione perfetta con la metodologia BEM.

Correlati: Abbracciare Sass: perché dovresti smettere di usare Vanilla CSS

Nell'esempio seguente, puoi vedere l'esempio più tipico di BEM, in combinazione con SASS:

 .person { &__hand {/* Styles */} &__leg {/* Styles */} &--male { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } &--female { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } }

Il codice SASS verrà compilato nel seguente CSS:

 .person__hand {/* Styles */} .person__leg {/* Styles */} .person--male {/* Styles */} .person--male__hand {/* Styles */} .person--male__hand--left {/* Styles */} .person--male__hand--right {/* Styles */} .person--male__leg {/* Styles */} .person--male__leg--left {/* Styles */} .person--male__leg--right {/* Styles */} .person--female {/* Styles */} .person--female__hand {/* Styles */} .person--female__hand--left {/* Styles */} .person--female__hand--right {/* Styles */} .person--female__leg {/* Styles */} .person--female__leg--left {/* Styles */} .person--female__leg--right {/* Styles */}

Se vuoi andare ancora oltre, puoi usare un pratico mixin SASS per BEM:

 /// Block Element /// @param {String} $element - Element's name @mixin element($element) { &__#{$element} { @content; } } /// Block Modifier /// @param {String} $modifier - Modifier's name @mixin modifier($modifier) { &--#{$modifier} { @content; } }

E puoi usarlo in questo modo:

 .person { @include element('hand') {/* Person hand */} @include element('leg') {/* Person leg */} @include modifier('male') { /* Person male */ @include element('hand') { /* Person male hand */ @include modifier('left') { /* Person male left hand */ } @include modifier('right') { /* Person male right hand */ } } } }

Che produrrà il seguente output CSS:

 .person__hand { /* Person hand */ } .person__leg { /* Person leg */ } .person--male { /* Person male */ } .person--male__hand { /* Person male hand */ } .person--male__hand--left { /* Person male left hand */ } .person--male__hand--right { /* Person male right hand */ }

So che molto probabilmente non avrai un caso d'uso così lungo, ma questo è un ottimo esempio di come viene utilizzato BEM e perché è così potente, sia in progetti su piccola che su larga scala.

Avvio del tuo progetto BEM

Come spiegato nella documentazione ufficiale BEM, il modo più semplice per iniziare a possedere un nuovo progetto BEM è utilizzare il repository GIT esistente. Usa semplicemente il comando Git clone:

 $ git clone https://github.com/bem/project-stub.git

Quindi, vai in una directory appena creata e installa tutte le dipendenze:

 $ npm install

Verranno installate tutte le dipendenze richieste:

Dipendenze BEM

Costruisci il progetto utilizzando ENB:

 $ node_modules/.bin/enb make

Esegui una modalità server per lo sviluppo:

 $ node_modules/.bin/enb server

Di conseguenza, viene visualizzato il seguente messaggio:

 Server started at 0.0.0.0:8080

Ora, questo significa che il server è attivo e funzionante. Ora puoi controllare i risultati a questo indirizzo:

 http://localhost:8080/desktop.bundles/index/index.html

Come puoi vedere, ci sono molti elementi già creati che sono definiti all'interno del file bemjson che si trova qui:

 project-stub/desktop.bundles/index/index.bemjson.js

Puoi vedere ed esplorare la struttura corrente del file che sta generando tutto quell'HTML, che vedi nel tuo file localhost index.html . Modificheremo questo file per ottenere il nostro progetto BEM "Persona" che abbiamo spiegato in un capitolo precedente. Puoi rimuovere (o commentare) l'intero codice dal file index.bemjson.js e sostituirlo con questo:

 module.exports = { block: 'page', title: 'Person BEM', favicon : '/favicon.ico', head : [ { elem : 'meta', attrs : { name : 'description', content : '' } }, { elem : 'meta', attrs : { name : 'viewport', content : 'width=device-width, initial-scale=1' } }, { elem : 'css', url : 'index.min.css' } ], scripts: [{ elem : 'js', url : 'index.min.js' }], content: [ { block: 'person', content: [ { elem: 'male', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Male person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Male person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Male person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Male person hand -- right' } ] }, { elem: 'female', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Female person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Female person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Female person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Female person hand -- right' } ] }, ] } ] };

Ora verrà generato il seguente codice HTML:

 <div class="person"> <div class="person__male"> <div class="person__leg person__leg_side_left"> Male person leg -- left </div> <div class="person__leg person__leg_side_right"> Male person leg -- right </div> <div class="person__hand person__hand_side_left"> Male person hand -- left </div> <div class="person__hand person__hand_side_right"> Male person hand -- right </div> </div> <div class="person__female"> <div class="person__leg person__leg_side_left"> Female person leg -- left </div> <div class="person__leg person__leg_side_right"> Female person leg -- right </div> <div class="person__hand person__hand_side_left"> Female person hand -- left </div> <div class="person__hand person__hand_side_right"> Female person hand -- right </div> </div> </div>

Come puoi vedere dal codice sopra, in questo scenario è stato utilizzato lo schema di codifica BEM predefinito poiché stiamo utilizzando solo le impostazioni predefinite che ci ha fornito BEM. Ci sono molti più comandi e opzioni che puoi esplorare e utilizzare, come la creazione di nuove pagine, blocchi o la modifica di BEM HTML. Non andrò troppo in profondità in questo, e tutto può essere trovato nella documentazione ufficiale BEM.

BEM Vantaggi e preoccupazioni

Vantaggi e preoccupazioni

Vantaggi

  • BEM è eccellente per il mantenimento. Quante volte hai dovuto lavorare dietro a qualcuno su un progetto su larga scala e hai troppa paura di cambiare qualcosa senza che qualcosa di sconosciuto crolli? Quando usi BEM, conosci lo scopo esatto dell'elemento e in quale blocco potrebbe apparire.
  • I nomi delle classi sono logici e intuitivi e ogni membro del team sa cosa fa quell'elemento sul sito web. BEM offre a tutti in un progetto una sintassi dichiarativa che possono condividere in modo che siano sulla stessa pagina.
  • BEM elimina i selettori CSS nidificati. Ogni singolo elemento HTML ha la sua classe CSS e dal suo nome sai qual è il suo scopo. Un selettore per dominarli tutti .

Preoccupazioni ed errori comuni

  • Non andare troppo in profondità nella nidificazione. La regola principale dovrebbe essere quella di non utilizzare più di due livelli di genitore e figlio.
  • Fai attenzione a dove inizi il tuo ambito di blocco. Un errore comune qui è quando uno sviluppatore usa il blocco, ma non si rende conto che in un punto successivo dello sviluppo quello stesso blocco avrà un blocco padre principale che potrebbe infrangere la regola con l'annidamento.
  • Evita SASS @extend. Per citare Harry Roberts su questo:

È possibile creare un numero maggiore di combinazioni nella vista non 'legando' le classi in Sass. L'HTML ha una traccia cartacea molto migliore in quanto puoi vedere ogni classe che agisce su un pezzo del DOM. Il tuo CSS rimane molto più sottile in quanto non devi creare nuove classi segnaposto (o le classi manifest che le combinano) ogni volta che vuoi creare un nuovo pezzo di interfaccia utente.

Conclusione

Quando ho visto per la prima volta lo schema di codifica BEM, il mio primo pensiero è stato:

Queste classi sono troppo lunghe per essere scritte e lette.

Ma dopo averlo provato, ora non riesco a immaginare di iniziare un nuovo progetto senza usarlo. Per quanto mi riguarda, BEM ha notevolmente migliorato la manutenibilità del mio codice e posso dire con certezza che ogni sviluppatore che verrà "lanciato" nel progetto basato su BEM raggiungerà molto rapidamente l'intera struttura del codice.

Nonostante tutto questo, sui social network si parla molto di BEM. Alcuni dicono che BEM non è buono, chiedendosi perché dovrebbero scrivere classi con nomi così lunghi invece di usare solo elementi nidificati HTML predefiniti. Bene, nessuno dice che ti debba piacere BEM, ma il fatto è che la maggior parte degli sviluppatori front-end lo abbraccia e lo trova straordinariamente utile.

Correlati: assumi il 3% più ricco di sviluppatori front-end freelance.