Compartir esta publicación

Compartir en facebook
Compartir en linkedin
Compartir en twitter
Compartir en email

Introducción

En mi anterior artículo abordé las ventajas que tiene utilizar ITCSS para organizar nuestros estilos, principalmente, de cara a proyectos grandes en donde trabajan varias personas. Su utilización hará que nuestra estructura sea mucho más ordenada y haga que los estilos de nuestra aplicación sean más mantenibles.

Solventado el problema de jerarquía y organización de nuestro proyecto, quedaría trabajar en una nomenclatura que nos ayude a tener un código autodocumentado y que se entienda mejor. Para esta tarea nos puede ayudar incluir la nomenclatura BEM junto a lo visto de ITCSS. En este artículo vamos a abordar un acercamiento a BEMIT y qué ventajas nos puede ofrecer.

¿Qué es BEMIT?

BEMIT es, sencillamente, BEM + ITCSS. Al igual que BEM, es una metodología de nomenclatura para definir las clases de los nodos HTML de nuestros proyectos. La idea surgió del propio Harry Roberts, creador de BEM, y consistía en agregar el sistema de jerarquías de ITCSS a BEM. Gracias a BEM los desarrolladores pueden saber cómo se relacionan las clases entre sí. Si vemos el siguiente código, podemos tener una idea bastante clara de cómo se relacionan las clases entre sí.

<div class="footer">
  <div class="footer__brand-wrapper">
    <img src="" alt="" class="footer__logo round-picture" />
    <h2 class="footer__tittle">Brand Name</h2>
  </div>
  <ul class="footer__menu">
    <li class="footer__item footer__item--active">Item 1</li>
    <li class="footer__item">Item 2</li>
    <li class="footer__item footer__item--disabled">Item 3</li>
  </ul>
  <p class="footer__info footer__info--gold">Lorem Ipsum</p>
</div>

Con este fragmento de código, sabemos rápidamente que footer, footer__brand-wrapper, footer__logo, footer__tittle, footer__item y footer__item–active están relacionados entre sí, mientras que round-picture es un bloque independiente. Esta información nos puede ayudar a poder hacer modificaciones o añadir nuevas clases con más seguridad. ¿Cuál es el problema? Que no nos ofrece una visión global sobre cómo se comportan, actúan o deberían implementarse nuevas reglas o las modificaciones sobre las clases ya existentes. Solo nos ofrece una visión relativa.

Para aumentar la robustez de BEM, lo utilizamos conjuntamente con ITCSS. Seguimos manteniendo los 3 tipos de clases: bloques, elementos y modificadores, pero les agregamos información sobre su uso y estado al añadirles prefijos y sufijos. Esto nos permite determinar exactamente qué tipo de trabajo puede desarrollar una clase, como poder utilizarla y donde encontrar definidas sus reglas. Veremos que estos prefijos están íntimamente relacionados con la estructura ITCSS que tengamos en nuestro proyecto.

Prefijos

Roberts nos sugiere que utilicemos una serie de prefijos para abordar la problemática que hemos comentado.

  • c-. Prefijo para Component (componente). Un componente siempre es un bloque BEM, es una parte concreta de la interfaz. Es una implementación muy concreta que hará que cualquier cambio sea seguro y solo afecte a ese componente en particular, sin repercutir negativamente en otros. Ningún otro nodo del documento se verá afectado. Son las clases más comunes y las que más se utilizan. Para verlo de forma más clara, vamos a convertir el código de nuestro footer con esta nueva nomenclatura:
<div class="c-footer">
  <div class="c-footer__brand-wrapper">
    <img src="" alt="" class="c-footer__logo round-picture" />
    <h2 class="c-footer__tittle">Brand Name</h2>
  </div>
  <ul class="c-footer__menu">
    <li class="c-footer__item c-footer__item--active">Item 1</li>
    <li class="c-footer__item">Item 2</li>
    <li class="c-footer__item c-footer__item--disabled">Item 3</li>
  </ul>
  <p class="c-footer__info c-footer__info--gold">Lorem Ipsum</p>
</div>

También se renombraría el nombre del fichero footer y de la clase en su scss (o css) correspondiente.

Con este sencillo cambio, sabemos que la clase footer es un componente, lo que nos indica que es segura y modificarlo solamente afectará a ese componente. Además nos indica en que capa se encuentra y en que archivo está definido.

  • o-. Prefijo para Object (Objeto). Son clases reutilizables en todo el proyecto de manera genérica. Esto quiere decir que un objeto puede aparecer en varios lugares de nuestra aplicación y carecer de contexto específico, por lo que es arriesgado modificarlos. Así que, gracias a nuestro prefijo -o, sabremos que si vamos a modificar las reglas de ese objeto, se pueden ver afectadas varias partes de nuestra aplicación. Realmente, estamos añadiendo un prefijo a nuestros objects de ITCSS para identificarlos y diferenciarlos de los componentes. Por ejemplo, en el siguiente formulario tenemos definida una clase para alinear al centro el texto, que es un objeto. Tendremos que renombrarla y hacer lo propio con el fichero y con el código css.
<form class="form">
  <div class="form__group">
    <label class="form__label">Choose a car: </label>
    <select class="form__dropdown">
      <option class="form__option o-ta-center">Volvo</option>
      <option class="form__option o-ta-center">Saab</option>
      <option class="form__option o-ta-center">Mercedes</option>
      <option class="form__option o-ta-center">Audi</option>
    </select>
  </div>
</form>
  • u-. Es el prefijo de Utility (utilidad). Son clases bastante particulares, ya que no son ni bloques, ni elementos ni modificadores. Son clases genéricas que aportan algún tipo de utilidad y suelen tener un !important. Por lo general, una vez creada esta clase no se debería modificar. No son obligatorias y, de hecho, si no tienes ninguna en tu proyecto sería incluso mejor.
.u-block {
  Display: block !important;
}
  • t-. Prefijo Theme (de tema). Hay veces en donde trabajamos con interfaces que ofrecen la posibilidad de ofrecer distintos temas, como puede ser un tema claro y otro oscuro. Estas clases, no están en un lugar específico, si no que acompañan a la clase que modifican y utilizan un selector anidado, ganando en especificidad a las clases únicas. Son muy específicas, no las verás a menos que tu aplicación cuente con la funcionalidad de trabajar con diferentes temas, pero no está de más saber de su existencia y utilidad.
c-btn {
  background-color: $main-color;
  color: $main-gray;
  display: inline-block;
  padding: 1em;

  &.t-dark {
    background-color: #main-color-dark;
    color: $white;
  }
}
  • s-. Prefijo de Scope (contexto o ámbito). Son clases que añaden contexto en una sección de la aplicación y se utilizan para resolver un problema bastante específico. Un ejemplo bastante común puede ser el código html que es introducido por un usuario a través de un editor de texto html (como pueden ser los WYSIWYG). En este contenido no habrá clases que sigan nuestro formato BEMIT, teniendo que aplicar estilos a los nodos internos con alguna clase auxiliar que nos permita tener acceso a ellos. Tendríamos así un segmento de nuestro código libre del resto del sistema, pero a la vez, controlada mediante el sufijo scope. En el CSS, estas reglas se definen dentro de su propia capa scope.
.s-editor-content {
  font: 16px;
  h1, h2, h3, h4, h5, h6 {
    font: bold 18px sans-serif;
  }
  a {
    color: $main-red;
    text-decoration: underline;
  }
}
  • is-, has-. Prefijo state (estado). Las clases de estado nos informan sobre el estado temporal de un nodo. Son las típicas clases controladas mediante javascript y que modifican el estado de nuestro html, como en un menú que aparece o desaparece, cambios de tamaño, color, etc. Cuentan con la utilidad añadida de ayudar a los desarrolladores a conocer los posibles estados en los que puede estar una parte de la interfaz. En el siguiente ejemplo, podemos ver un ejemplo de clase dinámica utilizando VueJS para una validación típica de un formulario:
<form class="c-form">
  <div class="c-form__group" :class="{ 'has-error': isValidName }">
    <label class="c-form__label">User Name</label>
    <input type="text" class="c-form__input">
  </div>
</form>


.c-form {
  &__group {
    border-color: $main-black;
    &.has-error {
      border-color: $error-red;
    }
  }
}
  • _. Prefijo para hacks. En ciertas ocasiones, bastante raras, puede que necesites añadir un clase al html para ayudar anular o modificar algo de forma temporal. Realmente, son el tipo de clases que deberías evitar usar siempre, no es aconsejado su uso pero aún así conviene saber de su existencia por si en casos extremos tenemos que recurrir a ellas. ¿Qué casos son esos? Se me ocurre que necesites aplicar un arreglo urgente a un bug que se ha detectado y no tienes tiempo a aplicar un refactor en ese preciso instante aunque una solución temporal si sea sencilla de aplicar. Entonces, puedes utilizar un hack. Pero, como he dicho, tiene que ser temporal y no se deben reutilizar o enlazar a otras clases.
._c-footer-mobile {
  height: 80px;
}
  • js-. Este tipo de clases se ha ido volviendo bastante común. El objetivo es seguir adecuadamente la separación de estilos y lógica de javascript juntos en un mismo selector. Es una forma bastante visible de que ese nodo tendrá un evento o comportamiento javascript vinculado. Además, nos añade la seguridad de poder trabajar nuestro css sin que afectemos a la parte de javascript, ya que estas clases no estarán vinculadas con estilos.
<span class="c-modal__button c-button js-close-modal">X</span>
  • qa-. Prefijo para QA (control de calidad). Por el nombre, podrás intuir el objetivo que pueden tener estas clases. Efectivamente, están enfocadas para el equipo de QA. No son muy frecuentes pero pueden ser bastante útiles. Si contamos con pruebas de automatización de la interfaz con herramientas como Selenium, sería una buena práctica separar los selectores de CSS de los hooks para dichas pruebas. En mi caso, nunca he llegado a utilizarlas, pero hay que tener constancia de que existen y si se da el caso de contar con pruebas automatizadas, es una opción a tener en cuenta.
<span class="c-message c-message--error qa-error-login">Login error</span>

Sufijos

Los sufijos tienen una única funcionalidad: servir de herramienta para controlar el comportamiento responsive de nuestra aplicación. Son clases que están asociadas a otras clases, normalmente utilidades, aunque también pueden ser objetos. Si tenemos una clase [email protected] estamos diciendo que esa clase es una utilidad que ocultará un elemento html cuando el tamaño de pantalla sea sm (que, en este caso, tenemos predefinido como un mixin). En código sería algo así:

.u-hidden {
  visibility: hidden;
  $\@md {
    @include sm {
      visibility: hidden;
    }
  }
}
<div class="c-user">
  <img class="c-user__photo [email protected]" />
</div>

Podemos observar que tiene la misma funcionalidad que la utilidad u-hidden, pero al añadir el prefijo @, sabremos que donde la utilicemos sólo afectará a la media query que tengamos definida para el tamaño de pantalla sm. Si, por el contrario, utilizáramos u-hidden, ocultaremos el componente en cualquier tamaño de pantalla.

Hay que tener en cuenta que este tipo de clases no deberían utilizarse para aplicar estilos responsive a un componente. Si queremos que nuestro componente tenga un comportamiento responsive, las reglas con sus respectivas media queries es mejor añadirlas en el CSS del selector.

Jerarquía del proyecto

Si seguimos la estructura de ficheros que vimos en el artículo anterior de ITCSS, solo vamos a observar un cambio, y es que se ha agregado la carpeta scopes. Dentro tendremos nuestro fichero de scopes y este, se importará en nuestro fichero general de estilos, el styles.scss.

yNyMnMRBVR8WNIPuL B wDjMeZjmScdGGKP9HuI6nPRnsJ9fC8d fxRIB2rvImKIYcBSb2FTHrY3WISWOj7TyQ6BcD4 QIIhdkIUgtR3Unt7pZrcbINPHZyAVEf34KsQFonamtT7

Conclusión (cuando usarlo)

BEM nos proporciona un sistema para comunicar de forma clara las relaciones entre los bloques y los elementos contenidos en ellos, ayudando a crear un estándar. ITCSS nos ofrece un sistema para estructurar nuestros ficheros de estilos y nos ayuda a localizar las reglas definidas en ellos, además de minimizar los conflictos propios de la herencia y la especificidad que tantos dolores de cabeza dan cuando nuestro proyecto empieza a crecer, tanto en tamaño como en personas.

BEMIT combina lo mejor de los dos. Podemos ofrecer al equipo de desarrollo una idea del alcance que tiene un elemento usando prefijos. Cuando vemos una o- sabemos donde se encuentra esa clase, puesto que es un objeto, y la implicación que puede tener su modificación. Además, al utilizar los sufijos @ para los elementos que necesitan un tratamiento receptivo particular,

BEMIT ofrece ventajas en todo tipo de proyectos, aunque es cierto que en aquellos que sean grandes y donde trabajan varias personas es donde mejor rendimiento puede ofrecer. De todos modos, yo acostumbro a hacerlo incluso en proyectos pequeños porque la organización de los ficheros y de las propias reglas CSS me facilitan mucho la lectura del código, así que si te convence su sintaxis y estructuración, puede ser buena idea utilizarlo siempre.

Por supuesto, este artículo sirve como un acercamiento, una breve muestra de lo que puede ofrecer. Abajo dejo enlaces a los artículos oficiales de Harry Roberts donde puedes expandir la información sobre este patrón y ver ejemplos ampliados para poder adentrarte en el uso de BEMIT.

Links de interés

Prefijos y sufijos en BEM: https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/

También puedes consultar mi anterior artículo sobre ITCSS aquí

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Suscríbete a nuestro boletín de noticias

Recibe actualizaciones de los últimos descubrimientos tecnológicos

Acerca de Apiumhub

Apiumhub reúne a una comunidad de desarrolladores y arquitectos de software para ayudarte a transformar tu idea en un producto potente y escalable. Nuestro Tech Hub se especializa en Arquitectura de Software, Desarrollo Web & Desarrollo de Aplicaciones Móviles. Aquí compartimos con usted consejos de la industria & mejores prácticas, basadas en nuestra experiencia.

Posts populares
Obtén nuestro Libro: Software Architecture Metrics

Global Software Architecture Summit '22

Reserva tu plaza!

Reserva

¿Tienes un proyecto desafiante?

Podemos trabajar juntos

Secured By miniOrange