BEM: guía completa para CSS modular con ejemplos

14min

Cuando los proyectos se hacen más complejos, resulta difícil estructurar y mantener el CSS. Es ahí donde necesitamos  escribir un CSS modular y estructurado, fácil de entender y de mantener.  La metodología BEM es una de las propuestas más utilizadas por los equipos de trabajo profesionales para conseguirlo.

Índice

¿Qué es BEM (Block Element Modifier) y por qué es importante?

BEM es una metodología de trabajo para la escritura del CSS. Corresponde a las siglas Block Element Modifier y básicamente permite definir el CSS agrupando las reglas en esos tres elementos, el bloque, el elemento y el modificador. Enseguida vamos a entrar en detalle para que puedas entenderlos bien.

Este método de estructurar el CSS permite que los componentes sean reutilizables y el código CSS fácil de mantener, sobre todo cuando varios componentes de un equipo necesitan trabajar sobre el mismo proyecto.

La clave de BEM se basa en fijar una manera clara y predecible para definir las clases CSS y otros selectores, lo cual nos ayuda a evitar conflictos, garantizar que cada componente esté claramente separado y se pueda reutilizar con más facilidad. Sus efectos positivos se aprecian sobre todo en proyectos medianos o grandes.

Fundamentos de la Metodología BEM

Antes de entrar en detalle sobre cómo aplicar BEM en una parte más práctica, vamos a conocer en mayor detalle sus principios fundamentales. Necesitas tenerlos claros para aprovechar al máximo esta metodología.

Conceptos clave: bloques, elementos y modificadores

Lo más importante para poder aplicar correctamente BEM es entender los tres conceptos clave: bloques, elementos y modificadores.

  • Bloques: la entidad principal. Representan un componente independiente dentro de la página, que opera por sí mismo. Habitualmente está formado por todo un marcado HTML para componer una parte de la página. Ejemplos de bloques pueden ser una tarjeta, un menú, o un formulario.
  • Elementos: Son partes de un bloque. Estos elementos tienen una función específica dentro del bloque pero no los encuentras solos por ahí. Un ejemplo podría ser el icono de un botón, el título de una tarjeta o un ítem de un menú.
  • Modificadores: Se utilizan para representar variaciones o estados de un bloque o un elemento. Por ejemplo, un botón que tiene una versión primaria y una secundaria, o una tarjeta en tonos claros y oscuros.

Cómo estructurar tus clases con BEM

Teniendo claros los conceptos básicos, podemos pasar a ver cómo estructurar las clases. Para ello usaremos la nomenclatura BEM. 

Vamos a verlo para un ejemplo típico de tarjeta (componente «card»). La tarjeta puede tener elementos como el título, que además puede que necesiten diversos modificadores como el tamaño del título.

Para definir un bloque se colocan el nombre del bloque, tal cual, como nombre de una clase.

.card

Como puedes apreciar, se suele usar el inglés para nombrar las clases, aunque esto es simplemente opcional. El uso del inglés o español para nombrar las clases es una decisión que debe tomar el equipo al inicio del proyecto.

Luego tenemos los elementos, que se nombran usando el nombre del bloque donde se encuentran, seguido de un par de guiones bajos y el nombre del elemento en sí.

.card__title

Por último, para los modificadores usamos dos guiones medios, pudiendo haber tanto modificadores para bloques como modificadores para elementos.

.card--dark
.card__title--big

Ejemplos básicos de nomenclatura en BEM

Pongamos un ejemplo práctico en el que tenemos un bloque para un menú de navegación.

El HTML, donde encuentras las distintas clases con la nomenclatura BEM podría ser más o menos así:

<nav class='menu'>
  <ul class='menu__list'>
    <li class='menu__item menu__item--active'>
      <a class='menu__link' href='#'>Inicio</a>
    </li>
    <li class='menu__item'>
      <a class='menu__link' href='#'>Acerca de</a>
    </li>
  </ul>
</nav>

Como puedes apreciar, .menu es el bloque. Luego tienes elementos como .menu__list o .menu__item. Por último hemos aplicado un modificador en .menu__item–active que indica que ese enlace en particular está activo.

Beneficios de utilizar BEM en tus proyectos de CSS

Como hemos dicho, usar BEM puede traernos algunos beneficios interesantes, sobre todo a la hora de trabajar de manera más organizada y en equipo. Éstos se notarán en proyectos medianos o grandes, que necesites mantener a lo largo de un tiempo.

Mejora la escalabilidad del código CSS

Uno de los mayores beneficios de usar BEM es la mejora de la escalabilidad del CSS del proyecto. Gracias a esta estructura es posible agregar CSS al proyecto de manera segura, evitando que las actualizaciones tengan riesgo de romper lo que ya funcionaba bien.

Facilita la colaboración en equipos de desarrollo

Es muy importante también porque establece un marco de trabajo claro para todo el equipo. Esto permite que todos los miembros sigan una estructura clara del nombrado y aplicación de clases, lo que aumenta la comprensión del CSS y evita que cada uno tome decisiones arbitrarias por su parte.

Aumenta la reutilización de componentes

Pero también resulta importante el grado de reutilización del CSS que nos ofrece BEM. Cada bloque está diseñado para ser independiente, lo cual significa que podemos usarlo todas las veces que sea necesaria en el proyecto y aplicarle más o menos elementos y modificadores, como sea necesario en cada caso.

Simplifica el mantenimiento y las actualizaciones

Al final, todos los beneficios expuestos anteriormente redundan en una mejora sustancial de las facilidades de  mantenimiento del código CSS. 

Reduce la posibilidad de conflictos en el CSS

La aplicación de las clases de elementos y modificadores también nos permiten evitar conflictos en el código de CSS, como la sobreescritura no deseada de reglas o la repetición del código, algo que es muy relevante en proyectos grandes con muchos desarrolladores.

Implementación de BEM en CSS

Ahora vamos a pasar a una parte más práctica en la que podrás ver los procesos típicos de BEM, como la creación de bloques, elementos y modificadores.

Creación de bloques: definición y uso

Sabiendo que un bloque en BEM es una entidad autónoma, podemos aplicarlo en cualquier elemento que pueda vivir por sí solo en la página. Por ejemplo, un formulario de inicio de sesión podría ser un bloque llamado login-form.

Podríamos tener el formulario de este modo.

<form class='login-form'>
  <!-- Elementos del formulario -->
</form>

Observa que no hay problema en nombrar el bloque con un guión en medio, ya que en los modificadores usamos siempre dos guiones medios.

Ahora nuestro CSS, podría definir los estilos del bloque así:

.login-form {
  max-width: 400px;
  margin: 0 0 32px 0;
  padding: 1rem;
  border: 1px solid #ccc;
}

Definición y estilización de elementos dentro de bloques

Los elementos son partes específicas dentro de un bloque. De este modo, en nuestro formulario de login podríamos tener un campo de texto y un botón de envío.

<form class='login-form'>
  <input class='login-form__field' type='text' placeholder='Usuario'>
  <button class='login-form__button' type='submit'>Entrar</button>
</form>

Como has podido observar, usamos dos guiones bajos para separar el nombre del bloque y de los elementos. En el CSS quedaría así:

.login-form__field {
  width: 100%;
  padding: 0.5rem;
  margin-bottom: 1rem;
}

.login-form__button {
  background-color: #007bff;
  color: #fff;
  padding: 0.75rem;
  border: none;
  cursor: pointer;
}

Aplicación de modificadores para variantes y estados

Ya por lo que respecta a los modificadores se pueden introducir todos los que se necesiten para cubrir los distintos estados del bloque o de los elementos. Por ejemplo podríamos tener un estado del campo de texto que presentase un error de entrada de datos.

<input class='login-form__field login-form__field--errored' type='text' placeholder='Usuario'>

Entonces en el CSS podríamos indicar que el borde del campo de texto debe ser rojo.

.login-form__field--errored {
  border-color: red;
}

Ejemplos prácticos de BEM

Para que puedas llevarte una idea más amplia de las posibilidades de la metodología BEM vamos a mostrarte otros ejemplos prácticos típicos de interfaces de usuario que podrías usar en tu día a día..

Ejemplo de estructura HTML y CSS para un botón

Vamos a ver un ejemplo práctico de cómo implementar un botón con diversos modificadores utilizando la metodología BEM:

<button class='button button--primary'>Enviar</button>

<button class='button button--secondary'>Cancelar</button>

En el CSS tendremos que definir los estilos de base para el bloque del botón y luego los estilos particulares para los modificadores:

.button {
  padding: 0.75rem 1.5rem;
  border: none;
  cursor: pointer;
}

.button--primary {
  background-color: #007bff;
  color: #fff;
}


.button--secondary {
  background-color: #6c757d;
  color: #fff;
}

Cómo usar BEM para diseñar un formulario

Ahora vamos a ver un ejemplo más completo de formulario con varios campos, que podríamos usar perfectamente como formulario de contacto en una página web:

<form class='contact-form'>
  <div class='contact-form__group'>
    <label for='name' class='contact-form__label'>Name</label>
    <input type='text' id='name' class='contact-form__input' placeholder='Enter your name' required>
  </div>

  <div class='contact-form__group'>
    <label for='email' class='contact-form__label'>Email</label>
    <input type='email' id='email' class='contact-form__input' placeholder='Enter your email' required>
  </div>

  <div class='contact-form__group'>
    <label for='message' class='contact-form__label'>Message</label>
    <textarea id='message' class='contact-form__textarea' placeholder='Enter your message' required></textarea>
  </div>

  <button type='submit' class='contact-form__button'>Send Message</button>
</form>

Cuando se trata de componentes de bloque un poco más grandes como este puedes observar que la declaración de nombres de clase se hace un poco más verbosa, pero aún así los beneficios de aplicar BEM siguen siendo patentes.

Veamos ahora el CSS:

.contact-form {
  width: 100%;
  max-width: 600px;
  margin: 0 0 32px 0;
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 10px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.contact-form__group {
  margin-bottom: 15px;
}

.contact-form__label {
  display: block;
  font-weight: 600;
  margin-bottom: 5px;
}

.contact-form__input,
.contact-form__textarea {
  width: 100%;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-sizing: border-box;
}

.contact-form__input:focus,
.contact-form__textarea:focus {
  border-color: #007bff;
  outline: none;
}

.contact-form__textarea {
  min-height: 150px;
}

.contact-form__button {
  width: 100%;
  padding: 12px;
  font-size: 16px;
  color: white;
  background-color: #007bff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-weight: 600;
}

Implementación de BEM en un layout de tarjeta de producto

Otro ejemplo típico donde podemos ver la aplicación de BEM es en una tarjeta de producto, que podrías usar en un comercio electrónico.

<div class='product-card'>
  <img class='product-card__image' src='producto.jpg' alt='Producto'>
  <h3 class='product-card__title'>Nombre del Producto</h3>
  <p class='product-card__description'>Descripción breve del producto.</p>
  <button class='product-card__button product-card__button--buy'>Comprar</button>
</div>

Ahora el CSS para estilizar este HTML podría verse como sigue:

.product-card {
  width: 300px;
  padding: 20px;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 10px;
  text-align: center;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.3s ease;
}

.product-card:hover {
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}


.product-card__image {
  width: 100%;
  height: auto;
  border-radius: 10px;
  margin-bottom: 15px;
}

.product-card__title {
  font-size: 1.5em;
  font-weight: 700;
  margin-bottom: 10px;
  color: #333;
}

.product-card__description {
  font-size: 1em;
  color: #666;
  margin-bottom: 20px;
}

.product-card__button {
  padding: 12px 20px;
  font-size: 1em;
  font-weight: 600;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.product-card__button--buy {
  background-color: #28a745;
  color: #fff;
}

.product-card__button--buy:hover {
  background-color: #218838;
}

Mejores prácticas para usar BEM

Antes de acabar todavía tenemos algunos puntos que pensamos esenciales a la hora de aplicar BEM de manera correcta. Vamos a ver a continuación una lista de las buenas prácticas que deberías asegurarte de seguir, tú y todo tu equipo.

Consistencia en la nomenclatura y el uso de clases

Antes de comenzar el proyecto es importante decidir unas normas básicas que nos aseguren una nomenclatura consistente en todo el proyecto. Por ejemplo, debemos estipular aspectos como el uso de nombres de clases sin abreviaciones, el idioma que vamos a usar al definir las clases, etc.

Mantenimiento y escalabilidad de CSS con BEM

Mediante la aplicación de BEM de manera transversal en todo el proyecto conseguiremos ahorrar trabajo a la larga, que se notará mucho en las fases de  mantenimiento del código CSS y su extensión. 

Para ello es importante seguir siempre BEM, definiendo y aplicando de manera escrupulosa los bloques, elementos y modificadores, sin saltarse las reglas. También resultará útil mantener una documentación, por ejemplo mediante una guía de estilos, que os ayude a seguir las normas y convenciones de manera uniforme y constante.

Integración de BEM con preprocesadores CSS (SASS, LESS)

Es normal que nos preguntemos si esta metodología se integra bien con herramientas habituales en el día a día de los desarrolladores frontend como SASS o LESS, incluso PostCSS. Por supuesto no existe ningún problema aquí, ya que el nombre de las clases que uses no tiene mucho que ver con estas tecnologías. En resumen, puedes seguir usando tus mismas herramientas de CSS tranquilamente para trabajar con BEM.

BEM en Angular: mejores prácticas

Cuando trabajamos con Angular, o cualquier otro framework basado en componentes que acepte estilos globales, tienes que seguir las recomendaciones de la metodología BEM que hemos explicado en este artículo. Simplemente usarás bloques para los estilos de los componentes principales y elementos para el propio marcado interno o los componentes secundarios. También tendrás que aplicar CSS para los modificadores que necesites, cuando un estilo sea condicional al estado del componente.

Errores comunes al usar BEM y cómo evitarlos

Ya para acabar vamos a abordar algunos errores frecuentes de los desarrolladores cuando empiezan a trabajar con la metodología BEM.

Uso incorrecto de la nomenclatura BEM

El error más frecuente es saltarse la nomenclatura, ya sea por no atender a la estructura adecuada que BEM propone para bloques, elementos o modificadores.

Otro error similar consiste en intercambiar accidentalmente el carácter de los guiones (bajos o altos) en los elementos o los modificadores. Al principio conviene prestar bastante atención, para asegurarse de seguir la sintaxis correcta.

Inconsistencia en la aplicación de modificadores

Quizás donde más dudas se encuentran los desarrolladores al aplicar correctamente la metodología BEM es en el uso de los modificadores. Es importante aplicar estilos base a los bloques o elementos y usar siempre modificadores para cambiar el CSS ante estados que se aplicarán unas veces sí y otras veces no.

El uso de modificadores debe ser consistente y atender a un nombrado sencillo y homogéneo. Además, antes de crear nuevos modificadores conviene verificar siempre el código CSS, para evitar redundancias por el hecho de crear diferentes nombres de modificadores para representar el mismo estado.

Falta de organización en la estructura de bloques

Otro error común ocurre cuando no organizamos adecuadamente los bloques y sus elementos. Es útil siempre separar el código por bloques de manera patente en el código. En este sentido lo mejor es colocar cada bloque en un archivo aparte y unirlos en el proceso de build de los assets con alguna herramienta como SASS o PostCSS. Esto te ayudará en la etapa de desarrollo pero sobre todo facilitará el mantenimiento y la optimización del código CSS.

Fernán García de Zúñiga

Productos relacionados: