2015. november 03.

Nevezzük a nevén: BEM

10 perc olvasási idő

Nevezzük a nevén: BEM

Mi is az a BEM? A kifejezés egy mozaikszó, mely a Block Element Modifier összetételre utal. Egy módszer CSS osztályaid elnevezésére, amely több jelentést és nagyobb átláthatóságot biztosít más fejlesztők számára. Sokkal informatívabb, ami a BEM elnevezést ideálissá teszi nagyobb projekteken dolgozó fejlesztők számára.

A módszert a Yandex Internetes cég csapata találta ki még 2009-ben, fő céljuk a fejlesztési folyamatok gyorsítása és a fejlesztők közötti csapat munka megkönnyítése volt.

Minek nevezzelek?

A módszer alapvetése, hogy a felület összetartozó elemeit blokkokba csoportosítva összefogja. Így az elnevezés során, minden elem hordozza magával a blokk nevét is, melyhez tartozik. Ennek teljesüléséhez szeparálnod szükséges a blokk és az elem megnevezését. Erre a dupla aláhúzást határozza meg (__) a módszer.  A következő példa jól szemlélteti ezt:


<nav class="menu__frame">
  <ul class="menu">
       <li class="menu__item">…</li>
       <li class="menu__item">…</li>
   </ul>
</nav>

Előfordul, hogy egy adott elem egyes tulajdonságaiban eltér a többitől, ezeket a tulajdonságokat egy módosítóval tudod hozzárendelni, amit egyszerű aláhúzással jelöl (_). Visszatérve az előző példához, a következőképpen fog kinézni:


<li class=“menu__item menu__item_current”>…</li>

Nem csak egy elem rendelkezhet módosító osztállyal, hanem maga a blokk is, amennyiben az egész blokk megjelenésén szeretnél módosítani.


<nav class=“menu__frame”>
   <ul class=“menu menu_hidden”>…</ul>
</nav>

A BEM kétféle módosítót különböztet meg, logikai (block-name_mod-name) és kulcs-érték típusú módosítókat (block-name_mod-name_mod-value). Előbbi megmutatkozik a fenti példában, a kulcs-érték típusú pedig így néz ki:


<nav class=“menu__frame”>
   <ul class=“menu menu_theme_morning-forest”>…</ul>
</nav>

Amit érdemes még megemlíteni, az a prefix-ek használata. A BEM ugyanis meghatároz négy használható előtagot, melyek az osztály jellegére utalnak:

  • b-class-name: blokk
  • h-class-name: pisztolytáska (holsters), több összetartozó elem összekapcsolására használható
  • l-class-name: layout
  • g-class-name: globális stílusok

<nav class=“b-menu__frame”>
   <u class=“b-menu”>…</ul>
</nav>

<section class=“g-cleared-container”>…</section>

BEM

Természetesen van néhány alapvető megkötés, melyeknek meg kell felelned az osztályok elnevezése során, ezek a következők:

  • az elnevezés számokból és kisbetűs latin karakterekből állhat
  • az egybefüggő szavakat kötőjellel választhatod el (-)
  • a blokkok, elemek és módosítók elnevezésének mindenképp beszédesnek és informatívnak kell lennie

Ahány ház, annyi szokás

Több alternatív elnevezési séma létezik, melyek mind a BEM módszerben meghatározottakon alapulnak.

Az egyik – talán legelterjedtebb – a Harry Roberts’ style, mely a következő mintát követi: block-name__elem-name–mod-name. A legfőbb eltérés, hogy a logikai módosítókat két kötőjellel (–) jelöli, illetve a kulcs-érték módosítók használatát elhagyja.

A legegyszerűbb alternatíva a CamelCase style, amiről a neve szinte mindent elárul. Az egybefüggő szavak szeparálására kötőjel helyett CamelCase-t használ.

Egy másik stílus az úgynevezett “Sans underscore” style, amely a szóösszetételek elválasztását a CamelCase style-hoz hasonlóan határozza meg. A blokkok és elemek szeparálására kötőjeleket használ (-), és a módosítókat Harry Roberts’ style alapján definiálja, azzal a kivétellel, hogy kulcs-érték módosítókat is használ. Így a minta a következőképpen fog kinézni: blockName-elemName–modName–modValue.

Ahogy az elnevezési sémára, úgy a prefix-ekre is születtek alternatívák. Közülük, amit a leghasznosabbnak találok, azok az állapotjelzők, melyeket egy is- előtag jelöl. Ezekhez az osztályokhoz állapotokat köthetsz pl.:


<nav class=“mobile-navigation is-active”>…</nav>


.mobile-navigation {
   display: none;
}
.mobile-navigation.is-active {
   display:block;
}

Személy szerint a legbarátságosabb sémának a Harry Roberts féle stílust találom, úgy gondolom, hogy mindenki szabadon kiválaszthatja a neki megfelelőt, vagy saját kénye-kedve szerint alakíthat ki egy új sémát, más jelölési rendszerrel, ami egyedülálló, de következetesen érvényesíti a BEM szemléletmódját.

Mindazonáltal, ne felejtsd el, hogy ebben a kérdésben a csapatnak kell konszenzusra jutnia, hisz a fő cél, a csapatmunka megkönnyítése.

Miért használnám…

… egyébként is ronda. Azt hiszem talán ez az egyetlen negatívum, ami a BEM ellen szól. Bár az is igaz, hogy ezt szinte minden bejegyzés, vagy cikk ki is emeli, ami a témáról ír.

Első benyomásom nekem sem volt másképp, az alulvonással jelölt szerkezetekkel és hosszú osztály nevekkel mondhatni nehezen sikerült megbarátkoznom, de úgy gondolom, hogy a megannyi előnyéért érdemes megkötnöd ezt a kompromisszumot.

Rendben, de mik is ezek az előnyök?

A BEM módszert követve

  • elkerülheted a leszármazottként történő hivatkozásokat
  • elkerülheted azt is, hogy a későbbi módosítások rákényszerítsenek kilométer hosszú szelektorok írására
  • végül elkerülheted, hogy a CSS tulajdonságok !important-tal küzdjenek meg egymással az életben maradásért.
  • az osztályaid egységet képezve sokkal átláthatóbbá teszik CSS kódod és nem mellesleg a HTML-ben felépített struktúrát is.
  • a kódod sokkal átláthatóbbá válik, az idő folyamán törlésre kerülő blokkokhoz tartozó osztályok könnyen azonosíthatóvá válnak, így a kódbázisod nem válik robusztussá.
  • a blokk név jelölésével kikristályosodnak az osztályok közötti függőségek is. Például egy list__item osztály esetén tudod, hogy függ a list osztálytól.
  • sokkal bátrabban fogsz a meglévő kódodhoz nyúlni, hiszen egy sor átírása után nem kell azzal szembesülnöd, hogy megváltoztak olyan elemek is, amelyekhez hozzá sem szerettél volna nyúlni.

BEM__preprocessor–sass

Aki már használt CSS preprocessorokat, annak nem kell bemutatni számtalan előnyét. Ezek közül az úgynevezett Nesting az, amit szeretnék kiemelni, mivel használatával még átláthatóbbá teheted a CSS kódodat, mégpedig így:


CSS
.article {…}
.article__title {…}
.article__lead {…}

SCSS
.article {
   […]
   &__title {…}
   &__lead {…}
}

Találkoztam már olyan megoldással, amely Mixinek használatával határozta meg az osztály neveket. Erről a css-tricks.com-on többet is olvashatsz. Személyes véleményem az, hogy a BEM és a Mixenek együttes alkalmazása feleslegesen túlbonyolítja a kódot, illetve annak átláthatóságát rontja. Ezzel pont a BEM egyik fő célja sérül.

Végszó

A BEM egy hasznos és hatékony módszer. Mi sem bizonyíthatná jobban, hogy egyre több projektben tűnik fel. Jó példa rá a BBC weboldala, vagy a Drupal 8. Használata egyszerű, bevezetése időigényes, viszont ez az idő mindenképp megtérül a projektek során, így mindenkinek csak ajánlani tudom használatát.

Tóth Gábor

Front-end fejlesztő. A letisztult megoldások híve, aki szerint nem elég, ha működik, annak jól is kell kinéznie. Ha épp nem programnyelven ír, akkor lírában.

Tóth Gábor

Hozzászólások