Introducere în Metodologia BEM

Publicat: 2022-03-11

Ce este metodologia BEM?

Când construiți site-uri web mai mici, modul în care vă organizați stilurile nu este de obicei o mare problemă. Vă creați fișierele obișnuite, scrieți toate CSS-urile necesare și atât. Cu toate acestea, atunci când vine vorba de proiecte mai mari și mai complexe, modul în care vă organizați codul devine crucial . Modul în care este structurat codul este și mai important dacă lucrați într-o echipă formată din mai mulți dezvoltatori front-end și back-end.

Metodologia BEM va îmbunătăți în mod masiv mentenabilitatea codului și va accelera procesul de dezvoltare

Metodologia BEM va îmbunătăți în mod masiv mentenabilitatea codului și va accelera procesul de dezvoltare
Tweet

Astăzi, există o mulțime de metodologii cu scopul de a reduce codul CSS și de a face codul CSS mai ușor de întreținut. În acest articol, voi explica și voi oferi câteva exemple ale unuia dintre ele: BEM. BEM înseamnă B lock E lement M odifier. Ideea principală din spatele acestuia este de a accelera procesul de dezvoltare și de a ușura munca în echipă a dezvoltatorilor prin aranjarea claselor CSS în module independente. Dacă ați văzut vreodată un nume de clasă precum header__form--search , acesta este BEM în acțiune. Da, clasele pot fi numite foarte lungi, dar toate sunt ușor de citit și de înțeles.

Rețineți că cea mai bună practică este să utilizați BEM numai cu clase, și nu cu ID-uri, deoarece clasele vă permit să repetați numele dacă este necesar și să creați o structură de codare mai consistentă. De asemenea, dacă doriți să vă împărțiți site-ul web în module organizate, acesta ar trebui să conțină aceeași structură: bloc, element și modificator. Unde fiecare bloc poate avea mai multe elemente și atât blocul, cât și elementele pot avea mai mulți modificatori. Cu toate acestea, să începem mai întâi cu structura BEM de bază și să o explicăm cu exemple.

bloc

Un bloc reprezintă un obiect din site-ul dvs. Gândiți-vă la asta ca la bucăți structurale mai mari ale codului dvs. Cele mai comune blocaje de pe fiecare site web astăzi sunt antetul, conținutul, bara laterală, subsolul și căutarea. Blocurile din BEM sunt întotdeauna un punct de plecare pentru înlănțuirea claselor dvs. CSS. Aruncă o privire la câteva exemple de bloc:

  • un continut
  • un meniu
  • un formular de căutare
 .content {/* Styles */} .menu {/* Styles */} .search {/* Styles */}

Element

Un element este o componentă din bloc care îndeplinește o anumită funcție. Ar trebui să aibă sens numai în contextul blocului său:

  • un articol de conținut
  • un articol de meniu
  • un câmp de introducere a căutării
 .content__article {/* Styles */} .menu__item {/* Styles */} .search__input {/* Styles */}

Modificator

Un modificator este modul în care reprezentăm variațiile unui bloc. Dacă ați folosit vreodată Bootstrap, atunci cel mai bun exemplu ar fi dimensiunea butoanelor. Dimensiunile butoanelor sunt doar variații de dimensiune ale butonului în sine, ceea ce îl face modificatorul:

  • un articol prezentat în conținut
  • un link de meniu
  • un câmp de căutare cu sau fără pictogramă
 .content__article--featured {/* Styles */} .menu__item--link {/* Styles */} .search__input--icon {/* Styles */}

Convențiile de denumire

Scopul principal al metodologiei BEM este de a face numele selectorilor CSS cât mai informative și transparente posibil. Stilul BEM original este definit în acest fel:

Numele blocului este de obicei un singur cuvânt precum .header , dar dacă aveți o definiție mai lungă a blocului, atunci acesta este împărțit cu o singură cratimă - :

 .lang-switcher {/* Styles */}

Numele elementului începe cu liniuță de subliniere dublă __ :

 .lang-switcher__flag {/* Styles */}

Numele modificatorului începe cu o singură liniuță de subliniere _ :

 .lang-switcher__flag_basic {/* Styles */}

Există o singură regulă foarte critică în metodologia BEM - un modificator nu poate fi folosit în afara contextului proprietarului său.

Exemplu:

 .btn_big {/* Styles */}

Puteți utiliza btn_big numai dacă este definit și antetul.

Exemplu prost:

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

Bun exemplu:

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

Pe lângă aceste stiluri BEM originale, există scheme alternative de denumire precum stilurile Harry Roberts și CamelCase.

Exemplu de stil Harry Roberts:

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

Exemplu de stil CamelCase:

 .BlockName__ElementName_ModifierName {/* Styles */}

Mai sunt și altele puține, dar acestea două sunt cele mai comune. Personal, sunt un fan al convenției de numire propusă de Harris Roberts, care are următoarele reguli:

  • Numele sunt scrise cu litere mici
  • Cuvintele din numele entităților BEM sunt separate printr-o cratimă -
  • Numele unui element este separat de numele unui bloc printr-o liniuță dublă __
  • Modificatorii booleeni sunt delimitați de cratime duble --
  • Modificatorii de tip cheie-valoare nu sunt utilizați

Motivul pentru care această convenție de denumire este mult mai bine formată decât altele este că puteți distinge cu ușurință elementul modificator de alții. În convențiile originale de denumire, modificatorul ar fi definit astfel:

 .block__element_modifier {/* Styles */}

Dar după cum puteți vedea, nu există o diferență foarte mare între un caracter de subliniere simplu și dublu. Pe de altă parte, cratima dublă oferă o separare curată și puteți vedea modificatorul instantaneu:

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

Exemplu BEM în diferite formate

Vă rugăm să rețineți că, pe lângă CSS, BEM este și foarte util în organizarea fișierelor dvs. JSON, XML, arbore sau orice format care acceptă imbricarea. Gândiți-vă la metodologia BEM ca la o modalitate bună de a vă construi interfața de utilizare.

HTML structurat în format BEM

Să luăm în considerare următorul HTML, structurat în format 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>

Același lucru poate fi realizat folosind formatul JSON și 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' } ] }

Organizarea sistemului de fișiere a unui proiect BEM

În BEM, este esențial să vă organizați fișierele într-un mod corect. BEM nu numai că vă oferă o organizare excelentă a claselor CSS și le face pe deplin de înțeles, dar vă oferă și o structură de fișiere foarte ușor de întreținut. Să luăm un exemplu de proiect, folosind tehnica de organizare a fișierelor BEM cu fișiere SASS:

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

După cum puteți vedea mai sus, doar văzând structura subfolderului din interiorul folderului principal, totul este clar și organizat. În acest fel, nu are nicio diferență cine lucrează după tine sau dacă lucrezi după cineva, pentru că este incredibil de ușor să urmezi același tipar.

Împărțirea proiectului BEM în platforme

Pe lângă doar organizarea fișierelor folosind tehnicile metodologiei BEM, puteți intra și în lucruri mai specifice. De exemplu, dacă construiți un proiect web care va fi pe deplin receptiv, iar clientul a specificat că unele blocuri de pe mobil sunt total diferite față de dispozitivele desktop, cel mai bine ar fi să împărțiți structura folderului BEM în platforme. Exemplu de organizare a butoanelor pe diverse platforme:

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

Rețineți că acesta este doar un exemplu dacă doriți să vă organizați întregul proiect folosind metodologia BEM. Arborele de fișiere cu structură BEM nu este obligatoriu pentru a utiliza corect BEM, puteți utiliza BEM doar în unele segmente ale proiectului. Până acum nu am folosit această organizare strictă a structurii de fișiere BEM în care fiecare element și modificator are fișierul creat. În schimb, creez doar o structură de fișiere pentru blocurile care au o declarație a elementelor și modificatorilor săi.

Organizarea arborelui unui proiect BEM

BEM în practică

Deoarece acum sunteți familiarizat cu convențiile de numire, voi demonstra metodologia BEM în practică. Să presupunem că avem acest cod HTML în acțiune:

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

Cu următorul marcaj CSS aplicat:

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

Acum, nu fi indus în eroare. În exemplele noastre de până acum am avut aproape întotdeauna un bloc, un element și un modificator, ceea ce nu trebuie să fie întotdeauna cazul.

De exemplu, să presupunem că avem un bloc numit person . O persoană are picioare și mâini, poate fi și femeie sau bărbat. Dacă vrem să definim o persoană de sex masculin cu mâna dreaptă, va arăta astfel:

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

Acum puteți vedea semnificația reală a BEM. Am definit o persoană care modificator este un gen. Deoarece nu contează dacă o persoană este bărbat sau femeie, are o mână, iar mâna este un element. Și din nou, fiecare persoană poate avea mâna dreaptă sau stângă, care este din nou un modificator.

Într-un alt caz, dacă vrem să definim o persoană generală cu o singură mână, o vom face astfel:

 .person__hand {/* Styles */}

După cum puteți observa, odată ce vă familiarizați cu BEM, este foarte ușor să vă structurați structura CSS și HTML cu acesta.

Utilizarea BEM cu preprocesoare CSS

Personal, nu îmi pot imagina să încep un proiect nou fără a folosi unul dintre preprocesoarele CSS. După cum știți cu toții, preprocesoarele sunt un lucru grozav și ne oferă o mulțime de beneficii și, cel mai important, se potrivesc perfect cu metodologia BEM.

Înrudit : Îmbrățișarea Sass: de ce ar trebui să încetați să utilizați Vanilla CSS

În exemplul următor, puteți vedea cel mai tipic exemplu de BEM, în combinație cu 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 */} } } }

Codul SASS se va compila în următorul 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 */}

Dacă doriți să mergeți și mai departe, puteți utiliza mixuri SASS la îndemână pentru 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; } }

Și îl poți folosi astfel:

 .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 */ } } } }

Care va produce următoarea ieșire 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 */ }

Știu că cel mai probabil nu veți avea un caz de utilizare atât de lung, dar acesta este un exemplu grozav al modului în care este utilizat BEM și de ce este atât de puternic, atât în ​​proiecte la scară mică, cât și la scară mare.

Pornirea proiectului BEM

După cum se explică în documentația oficială BEM, cel mai simplu mod de a începe propriul proiect BEM nou este să utilizați depozitul GIT existent. Pur și simplu utilizați comanda Git clone:

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

Apoi, mergeți la un director nou creat și instalați toate dependențele:

 $ npm install

Toate dependențele necesare vor fi instalate:

Dependențe BEM

Construiți proiectul folosind ENB:

 $ node_modules/.bin/enb make

Rulați un mod server pentru dezvoltare:

 $ node_modules/.bin/enb server

Ca urmare, apare următorul mesaj:

 Server started at 0.0.0.0:8080

Acum, asta înseamnă că serverul este în funcțiune. Acum puteți verifica rezultatele la această adresă:

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

După cum puteți vedea, există o mulțime de elemente deja create care sunt definite în fișierul bemjson care se află aici:

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

Puteți vedea și explora structura curentă a fișierului care generează tot acel HTML, pe care îl vedeți în fișierul localhost index.html . Vom modifica acest fișier pentru a obține proiectul nostru BEM „Persoană”, pe care l-am explicat într-un capitol anterior. Puteți elimina (sau comenta) întregul cod din fișierul index.bemjson.js și îl puteți înlocui cu acesta:

 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' } ] }, ] } ] };

Acum, următorul HTML va fi generat:

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

După cum puteți vedea din codul de mai sus, schema de codare BEM implicită a fost utilizată în acest scenariu, deoarece utilizăm doar setările implicite pe care ni le-a furnizat BEM. Există mult mai multe comenzi și opțiuni pe care le puteți explora și utiliza, cum ar fi crearea de noi pagini, blocuri sau modificarea HTML BEM. Nu voi intra prea adânc în acest lucru și totul poate fi găsit în documentația oficială BEM.

BEM Avantaje și preocupări

Avantaje și preocupări

Avantaje

  • BEM este excelent pentru întreținere. De câte ori ai fost nevoit să lucrezi după cineva la un proiect la scară largă și ți-e prea frică să schimbi ceva fără ca ceva necunoscut să se prăbușească? Când utilizați BEM, cunoașteți scopul exact al elementului și în ce bloc poate apărea.
  • Numele claselor sunt logice și intuitive și fiecare membru al echipei știe ce face acel element pe site. BEM oferă tuturor participanților la un proiect o sintaxă declarativă pe care o pot partaja, astfel încât să fie pe aceeași pagină.
  • BEM elimină selectoarele CSS imbricate. Fiecare element HTML are propria sa clasă CSS și, după numele său, știți care este scopul său. Un singur selector pentru a le guverna pe toate .

Preocupări și greșeli frecvente

  • Nu intrați prea adânc în cuibărit. Regula principală ar trebui să fie să nu folosiți mai mult de două niveluri de părinte și copil.
  • Aveți grijă de unde începeți domeniul de aplicare al blocului. O greșeală obișnuită aici este atunci când un dezvoltator folosește bloc, dar el nu își dă seama că, la un moment ulterior al dezvoltării, același bloc va avea bloc părinte principal, care poate încălca regula cu imbricarea.
  • Evitați SASS @extend. Pentru a-l cita pe Harry Roberts despre asta:

Puteți crea un număr mai mare de combinații în vizualizare fără a „lega” clasele împreună în Sass. HTML-ul are o urmă de hârtie mult mai bună, deoarece puteți vedea fiecare clasă acționând pe o bucată din DOM. CSS-ul dvs. rămâne mult mai subțire, deoarece nu trebuie să creați noi clase de substituenți (sau clasele manifest care le combină) de fiecare dată când doriți să creați o nouă bucată de UI.

Concluzie

Când am văzut schema de codare BEM pentru prima dată, primul meu gând a fost:

Aceste cursuri sunt prea lungi pentru a fi scrise și citite.

Dar după ce l-am încercat, acum nu îmi pot imagina să încep un nou proiect fără să-l folosesc. Pentru mine, BEM mi-a îmbunătățit masiv mentenabilitatea codului și pot spune cu siguranță că fiecare dezvoltator care va fi „aruncat” în proiectul bazat pe BEM va ajunge foarte repede din urmă cu întreaga structură a codului.

Cu toate acestea, pe rețelele de socializare se discută mult despre BEM. Unii spun că BEM nu este bun, întrebându-se de ce ar trebui să scrie astfel de clase de nume lungi în loc să folosească doar elemente imbricate HTML implicite. Ei bine, nimeni nu spune că trebuie să vă placă BEM, dar adevărul este că majoritatea dezvoltatorilor front-end îl îmbrățișează și îl consideră extraordinar de util.

Înrudit: Angajați primii 3% dintre dezvoltatorii front-end independenți.