BEM: Bloque, Elemento y Modificador
Definir convenciones para nombrar selectores en CSS es ampliamente útil para hacer un código más estricto, transparente e informativo. Una buena convención de nombres debe estar en capacidad de comunicar:
- Qué tipo de cosas hace una clase
- Dónde se puede usar una clase
- Con qué otra clase podría estar relacionada
Guías generales
- Mantenga las clases en minúsculas y utilice guiones para hacer rupturas naturales en la clase relacionada (e.g
.btn
ybtn-danger
), - Evite la notación taquigráfica excesiva y arbitraria. La clase
.btn
es útil para el botón, pero.s
no significa nada. - Mantenga las clases lo más cortas y concisas posible.
- Use nombres significativos.
- Utilice nombres estructurales o intencionados sobre nombres presentacionales.
- Establezca prefijos basados en la clases padre más cercana.
Nombramiento BEM
BEM que significa Block, Element, Modifier es una metodología front-end adoptada por desarrolladores que trabajan en Yandex. Si bien BEM es una metodología completa, generalmente solo utilizo su convención de nomenclatura. BEM divide las clases de componentes en tres grupos:
- Block: El componente raíz
- Element: Un sub-componente que es parte del bloque
- Modifier: Una variante o una extensión del bloque
Una analogía asertiva para ilustrar BEM es la siguiente:
.person {} // Block
.person__head {} // Element
.person--tall {} // Modifier
Los elementos son delimitados con dos guiones bajos consecutivos (
__
) y los modificadores son delimitados por dos guiones consecutivos (--
)
Podemos observar que .person
es el bloque y es la única raíz de una entidad discreta. person__head
es un elemento y representa una parte más pequeña del bloque. Finalmente, person--tall
es un modificador y representa una variante específica del bloque person
.
Contexto de inicio
El contexto de un bloque comienza con una ubicación lógica, autónoma y discreta. Continuando con la analogía basada en la persona, no tendríamos una clase como .room_person
ya que la sala es otro contexto mucho más elevado. Probablemente los bloques estarías separados así:
.room {}
.room__door{}
.room--kitchen{}
.person {}
.person__head {}
.person--tall {}
Si quisiéramos denotar un .person
dentro de un .room
es más convenientes utilizar el siguiente selector:
.room .person {}
Un ejemplo más realista de bloques con un alcance adecuado se ilustra a continuación:
.page {}
.content {}
.sub-content {}
.footer {
.footer__copyright {}
}
Como se puede observar, cada fragmento de código representa su propio bloque. Una notación incorrecta sería:
.page {
.page__content {}
.page__sub-content {}
.page__footer {}
.page__copyright {}
}
Es importante saber cuando se inicia y detiene el alcance de BEM. Como regla general, BEM se aplica a partes independientes y discretas de la interfaz de usuario
Más capas
Si agregáramos otro elemento llamado .person__eye
al bloque person
, no tendríamos que pasar por cada capa del DOM. Es decir, la notación correcta sería .person__eye
y no .person__head__eye
. Las clases no reflejan el rastro completo del DOM. Por ende se recomienda evitar multiples sub-elementos dentro de un nombre de clase.