La siguiente es una publicación colaborativa del invitado Joe Richardson, Robin Rendle y un grupo del personal de CSS-Tricks. Joe quería hacer una publicación sobre BEM, que nos encantó, y casi todo el mundo aquí tenía pensamientos y opiniones sobre BEM, así que pensamos que nos reuniríamos todos y lo haríamos juntos.
El Bloque, elemento, modificador La metodología (comúnmente conocida como BEM) es una convención de nomenclatura popular para clases en HTML y CSS. Desarrollado por el equipo de Yandex, su objetivo es ayudar a los desarrolladores a comprender mejor la relación entre HTML y CSS en un proyecto determinado.
A continuación, se muestra un ejemplo de lo que podría escribir un desarrollador de CSS que escriba en el estilo BEM:
/* Block component */
.btn {}
/* Element that depends upon the block */
.btn__price {}
/* Modifier that changes the style of the block */
.btn--orange {}
.btn--big {}
En esta metodología CSS un cuadra es una abstracción de nivel superior de un nuevo componente, por ejemplo, un botón: .btn { }
. Este bloque debe considerarse un padre. Elementos secundarios, o elementos, se puede colocar dentro y estos se indican con dos guiones bajos después del nombre del bloque como .btn__price { }
. Por fin, modificadores puede manipular el bloque para que podamos aplicar un tema o estilo a ese componente en particular sin infligir cambios en un módulo completamente no relacionado. Esto se hace agregando dos guiones al nombre del bloque como btn--orange
.
El marcado podría verse así:
<a class="btn btn--big btn--orange" href="https://css-tricks.com">
<span class="btn__price">$9.99</span>
<span class="btn__text">Subscribe</span>
</a>
Si otro desarrollador escribió este marcado y no estábamos familiarizados con el CSS, aún deberíamos tener una buena idea de qué clases son responsables de qué y cómo dependen unas de otras. Luego, los desarrolladores pueden construir sus propios componentes y modificar el bloque existente al contenido de su corazón. Sin escribir mucho CSS, los desarrolladores son potencialmente capaces de crear muchas combinaciones diferentes de botones simplemente cambiando una clase en el marcado:
Vea el ejemplo de Pen BEM de Programar Plus(@ css-tricks) en CodePen.
Al principio, esta sintaxis puede parecer más lenta que simplemente crear una nueva clase para cada tipo de botón, pero este no es el caso por varias razones que cubriremos.
¿Por qué deberíamos considerar BEM?
- Si queremos crear un nuevo estilo de un componente, podemos ver fácilmente qué modificadores y elementos secundarios ya existen. Incluso podríamos darnos cuenta de que no necesitamos escribir ningún CSS en primer lugar porque hay un modificador preexistente que hace lo que necesitamos.
- Si estamos leyendo el marcado en lugar de CSS, deberíamos poder tener una idea rápida de qué elemento depende de otro (en el ejemplo anterior podemos ver que
.btn__price
depende de.btn
, incluso si no sabemos qué hace eso todavía). - Los diseñadores y desarrolladores pueden nombrar componentes de manera consistente para facilitar la comunicación entre los miembros del equipo. En otras palabras, BEM les da a todos en un proyecto una sintaxis declarativa que pueden compartir para que estén en la misma página.
Harry Roberts identificó otro beneficio clave de usar una sintaxis como BEM cuando escribe sobre cómo mejorar la confianza del desarrollador:
Esta es la razón principal por la que terminamos con bases de código infladas, llenas de CSS heredado y desconocido que no nos atrevemos a tocar. Carecemos de la confianza para poder trabajar con estilos existentes y modificarlos porque tememos las consecuencias de la naturaleza global y con fugas de CSS. Casi todos los problemas con CSS a gran escala se reducen a la confianza (o la falta de ella): la gente ya no sabe qué hacen las cosas. La gente no se atreve a hacer cambios porque no sabe hasta qué punto llegarán los efectos.
Asimismo, Philip Walton sostiene que este problema se puede solucionar si suficientes desarrolladores se adhieren a los principios de BEM:
Si bien es posible que nunca sea posible un código 100% predecible, es importante comprender las compensaciones que realiza con las convenciones que elija. Si sigue las convenciones estrictas de BEM, podrá actualizar y agregar a su CSS en el futuro con la plena confianza de que sus cambios no tendrán efectos secundarios.
Entonces, si los desarrolladores pueden trabajar en un proyecto con más confianza, seguramente tomarán decisiones más inteligentes sobre cómo se deben usar estos componentes visuales. Es posible que esta metodología no sea una cura perfecta para todas estas dolencias, pero ciertamente les brinda a los desarrolladores un estándar sobre el cual escribir un código mejor y más fácil de mantener en el futuro.
Otra parte inteligente de BEM es que todo es una clase y nada esta anidado. Eso hace que la especificidad de CSS sea muy plana y baja, lo cual es una buena idea. Significa que no terminarás peleando contigo mismo por la especificidad.
Echemos un vistazo a algunos de los problemas con BEM …
Problemas con BEM CSS
Por supuesto, nadie te torcerá el brazo si rompes las reglas de BEM. Aún podría escribir un selector de CSS como este:
.nav .nav__listItem .btn--orange {
background-color: green;
}
Parece que tiene partes de BEM en marcha, pero no es BEM. Tiene selectores anidados y el modificador ni siquiera describe con precisión lo que está sucediendo. Si hiciéramos esto, estaríamos arruinando la planitud de especificidad que es tan útil con BEM.
Un bloque (como .nav
) nunca debe anular los estilos de otro bloque o modificador (como .btn--orange
). De lo contrario, esto haría casi imposible leer el HTML y comprender lo que hace este componente; en el proceso, estamos obligados a sacudir en gran medida la confianza de otro desarrollador en el código base. Esto también se aplica a HTML: ¿qué esperarías si vieras el siguiente marcado?
<a class="btn" href="https://css-tricks.com">
<div class="nav__listItem">Item one</div>
<div class="nav__listItem">Item two</div>
</a>
Lo que probablemente está sucediendo aquí es que un elemento en un bloque completamente no relacionado tiene el código que un desarrollador necesitaba, pero los elementos secundarios no requieren un .nav
class como padre. Esto lo convierte en una base de código excepcionalmente confusa e inconsistente que debe evitarse a toda costa. Entonces podemos resumir estos problemas de la siguiente manera:
- Nunca anular modificadores en un bloque no relacionado.
- Evitar hacer elementos padres innecesarios cuando el niño puede existir felizmente por sí mismo.
Más ejemplos de BEM en acción
Demostración de acordeón
Vea Pen BEM Accordion de Programar Plus(@ css-tricks) en CodePen.
En este ejemplo hay un bloque, dos elementos y un modificador. Aquí podemos crear un .accordion__copy–open
modificador que nos permite saber que no debemos usarlo en otro bloque o elemento.
Demostración de navegación
Consulte el menú Pen BEM de Programar Plus(@ css-tricks) en CodePen.
Esta demostración de navegación tiene 1 bloque, 6 elementos y 1 modificador. Incluso está perfectamente bien crear bloques sin modificadores. En algún momento en el futuro, un desarrollador siempre puede agregar (o unirse) nuevos modificadores siempre que el bloque permanezca consistente.
No le gusta BEM
Tal vez no le gusten los guiones bajos o los guiones dobles. Bien, use algo más que sea único que hará cumplir constantemente.
Aquí hay otro sentimiento:
No estoy seguro de estar vendido en BEM. .site-search .site-search__field .site-search-full Por qué no: .site-search .site-search input .site-search .full
– Samuel Fine (@samuelfine) 11 de marzo de 2015
Los tres últimos selectores tienen todos diferentes niveles de especificidad. Requieren padres o no. Sin reglas establecidas, no dicen tanto como los que están arriba.
¿Es posible que este pequeño y aislado ejemplo te sienta perfectamente bien y nunca termine mordiéndote en el trasero? Quizás. Pero cuanto más CSS tenga en un proyecto, más cosas pequeñas como esta se suman, más batallas de especificidad y complejidad atravesarán.
BEM suena muy útil si no sabes cómo funcionan HTML o CSS.
– Samuel Fine (@samuelfine) 11 de marzo de 2015
No quiero molestar a Samuel aquí, pero sus sentimientos son compartidos por muchas personas, por lo que es un buen ejemplo. Ven BEM y simplemente lo rechazan. Si quieres que no te guste BEM, está absolutamente bien, pero creo que sería difícil argumentar que tener un conjunto de reglas que ayudar a comprender y ayudar a mantener CSS mantenible es una mala idea.
En la metodología SMACSS, es probable que encuentre un nombre de clase CSS con tres letras. Luego, los modificadores siguen el nombre del módulo con un guión:
/* Example Module */
.btn { }
/* Modifier of the btn class */
.btn-primary { }
/* Btn Module with State */
.btn.is-collapsed { }
Eso es solo un enfoque de nomenclatura diferente para el mismo tipo de problema. Es bastante similar, pero solo estás siendo más específico sobre las dependencias y manteniendo la especificidad más plana.
En OOCSS, los bloques son igualmente genéricos.
/* Example Module */
.mod { }
/* Part of Module */
.inner { }
/* Talk Module */
.talk { }
/* Variation of part inside Module */
.talk .inner { }
Entonces, usaría múltiples clases en el HTML para variaciones. La parte interior no se nombra como si tuviera una dependencia, por lo que es menos clara pero potencialmente más reutilizable. BEM haría .mod__inner
y .mod--talk
y .mod--talk__inner
.
Estas son solo variaciones de la metodología. Recuerda que nadie te está torciendo el brazo aquí, estas son reglas autoimpuestas donde el valor proviene de seguirlas.
Sass y BEM
Para aquellos de ustedes que escriben Sass y disfrutan de la anidación como una forma de definir el alcance de los estilos, aún pueden crear en un formato anidado, pero obtener CSS que no esté anidado, con @at-root
:
.block {
@at-root #{&}__element {
}
@at-root #{&}--modifier {
}
}
Te consigue:
.block {
}
.block__element {
}
.block--modifier {
}
¡Y puedes ser tan abstracto como quieras! Vea BEM Constructor de Danield Guillan o Expressive BEM de Anders Schmidt Hansen.
Resumen
Para resumir, creo que es justo decir que aunque BEM no resolverá todos nuestros problemas, es extraordinariamente útil para construir interfaces escalables y fáciles de mantener en las que todos los miembros del equipo deberían tener una idea clara de cómo se pueden mejorar las cosas. Esto se debe a que gran parte del desarrollo de la interfaz no se trata solo de los buenos trucos que resuelven un pequeño problema a corto plazo; necesitamos acuerdos, promesas y contratos sociales vinculantes entre desarrolladores para que nuestro código base pueda adaptarse con el tiempo.
Generalmente me gusta pensar en BEM como una respuesta a la pregunta de Nicolas Gallagher:
Reemplaza “¿puedes construir esto?” con “¿puedes mantener esto sin perder la cabeza?”
– Nicolas Gallagher (@necolas) 24 de julio de 2013
Otras lecturas
- El sitio web del proyecto BEM
- Efectos secundarios en CSS
- Encadenamiento de modificadores de BEM
- Principios BEM
- Código de interfaz de usuario más transparente con espacios de nombres