O webu
BEM: způsob zápisu CSS
.blok {}
.blok__element {}
.blok--modifikator {}

Nejjednodušší příklad použití této konvence pojmenování tříd může vypadat následovně.

<button class="tlacitko tlacitko--dulezite">
  <span class="tlacitko__popis">Koupit za</span>
  <span class="tlacitko__cena">500 Kč</span>
</button> 

S CSS selektory:

.tlacitko {}
.tlacitko--dulezite {}
.tlacitko__popis {}
.tlacitko__cena {}
Block

Blokem je v tomto případě třída tlacitko.

Element

Elementy jsou potomci bloku, tedy třídy tlacitko__popis a tlacitko__cena.

Modifier

Modifikátorem je třída tlacitko--dulezite.

Principy BEM

Hlavní princip BEMu boří jeden z hlavních pilířů kaskádových stylů – kaskádovitost. Vůbec se nepoužívá zanořování. Každý element má svou třídu, podle které je jednoznačně identifikován.

To má některé výhody.

Zanořování a dědičnost

HTML/CSS kodér se nemusí tolik prát s dědičností a sílou selektorů. Síla selektorů je pouze na úrovni prosté třídy.

Původní příklad bez použití BEMu by mohl vypadat následovně.

<button class="tlacitko dulezite">
  <span class="popis">Koupit za</span>
  <span class="cena">500 Kč</span>
</button> 

Adekvátní CSS by vypadalo následovně:

.tlacitko {}
.tlacitko.dulezite {}
.tlacitko .popis {}
.tlactiko .cena {}

Problém potom může nastat v případě, že by někde na stránce měl existovat blok s názvem popis:

<div class="popis">
…
</div>

Jeho styly pro selektor .popis {} by se potom promítly i do <button class="tlacitko popis">. Stejně tak by se styly pro blok .dulezite promítly do <button class="tlacitko dulezite">.

Konflikt tak při používání BEMu může nastat jen na úrovni bloků, což je menší risiko, než při zanořování selektorů.

Srozumitelnost kódu

Jelikož se styly nemohou dědit napříč různými bloky a každý stylovaný element má svou CSS třídu, je snazší k HTML elementu dohledat jeho selektor. Není kvůli tomu nutné používat vývojářské nástroje. Na druhou stranu to přináší nároky na vyšší složitost HTML kódu, kde se píší třídy i v místech, kdy by šlo použít obecný kontext (.navigace a).

<div class="navigace">
  <a href="#" class="navigace__odkaz">Odkaz</a>
  <a href="#" class="navigace__odkaz">Odkaz</a>
</div>

Používání konvence BEM tedy přináší něco za něco. Vyžaduje sice trochu více psaní, výsledek ale může být srozumitelný a lépe přenositelný mezi projekty, protože je menší risiko, že dojde ke kolisi v názvech.

Používat BEM?

Postup Block, Element, Modifier může být užitečný jako společná konvence při práci hodně lidí nad stejným CSS, kdy je jasně patrné, co která třída je.

Jde použít i nějaký kompromis, kdy se alespoň v rámci bloku používají třídy s názvem bloku na začátku:

<button class="tlacitko tlacitko-dulezite">
  <span class="tlacitko-popis">Koupit za</span>
  <span class="tlacitko-cena">500 Kč</span>
</button> 

Nebo si zvolit jinou konvenci pro znázornění elementu a modifikátoru. Například Martin Michálek nepoužívá spojovníky v názvech tříd, takže může používat následující zjednodušení.

.blok {}
.blok-element {}
.blok--modifikator {}

Omezit kolise v názvech tříd může i postup, který popsal Pepa Linha:

To spočívá v tom, že tzv. blok z metodiky BEM zapíše s prefixem „c-“, načež všechny třídy, co k němu patří, do něj zanořuje s využitím CSS preprocesoru.

.c-blok {  
  .element {}
  &.-modifikator {}
}

Výhodou je, že se v HTML kódu nemusejí neustále opakovat názvy bloků u elementů a modifikátorů. Nevýhoda je potom menší neprůstřelnost k stejně pojmenovaným třídám a vyšší váha selektorů.

Odkazy jinam