Una nueva metodología CSS

Problema

Cuando estamos en un gran proyecto, cuando usamos bibliotecas con shadow DOM que prescinden del HTML y/o cuando estamos en un proyecto muy iterativo, resulta muy a menudo difícil para mantener y hacer evolucionar la maquetación sin meterse en fregados de cierta importancia que necesitan reescribir plantillas, cada vez más a menudo incrustadas dentro de archivos JS y que puede provocar que varias personas del equipo (¡o peor, varios equipos!) entren en conflicto.

La separación entre la vista y la lógica de la aplicación, en teoría una cosa tan beneficiosa, en la realidad se da poco y cada vez menos en aras del rendimiento. Pero es en mi opinión un error. No deberíamos tener que tocar un HTML y menos un JS cuando lo único que queremos es cambiar un estilo, pero nuestro código está lleno de clases del tipo “big-button”, “left-column”, “sidebar”, “top-menu”, “float-left”, clases que hacen referencia directa al aspecto del elemento en cuestión y no a su función. Y que nos obliga a que si consideramos que el big button no debería ser tan big, tengamos que cambiar no el CSS sino la plantilla.

Objetivo

Creo que sería muy beneficioso hacer que cualquier cambio únicamente visual de una aplicación o site, pasase solo por el CSS sin necesidad de cambiar una sola línea de HTML, sin tener que quitar ni poner clases. Y hacer que la metodología de clases a su vez respetase la estructura de componentes. Todo mucho más legible, más semántico, más claro, right?

Reglas

Nomenclatura

Utilizaremos para las clases un sistema de nombres evolucionado de SUIT CSS.

NombreComponente-nombreDescendiente
NombreComponente--variacionComponente
entorno-NombreComponente

Limitación a una clase identificadora por elemento

Emplearemos una sola clase por elemento, más las clases de estado que sean necesarias. Nada de acumular clases ni de repetir la clase base más la variación. ¿Qué logramos con esto? Especificidad máxima, máxima eficiencia del CSS (que en realidad tampoco es algo que importe tanto, al menos en el 99% de las veces), limitamos la cantidad de potenciales overrides y conflictos.

<div class=”ComponentName-element is-active”></div>

Clases semánticas

Todas las clases serán puramente semánticas, se referirán única y exclusivamente al contenido o acción lanzada por el elemento, jamás a su aspecto, posición, formato o tipo de componente. Así pues, lo que según un método anterior podría haberse llamado:

<div class="box aside login">
<button class=”button button-submit”></button>
</div>

Ahora sería:

<div class="Login--quickAccess">
<a class=”Login--quickAccess-submit”></a>
</div>

Esto tiene varias ventajas. Si la funcionalidad permanece inalterada, una aplicación podría ser completamente rediseñada sin cambiar una sola coma en las plantillas. Si la estructura de información es la misma, el cambio visual no debería tener un impacto sobre los archivos que contienene la lógica y la estructura de datos. Por otro lado, me he dado cuenta de que de este modo, pasar de la fase de definición de la arquitectura de la información a una maqueta es muy sencillo, e incluso extender este camino hacia la generación de componentes Javascript.

Si tienes la idea de un listado de noticias que contenga… noticias, obviamente, puedes producir un prototipo estático del tipo:

<div class="NewsList">
<div class="NewsItem">
<div class="NewsItem-title">...</div>
<div class="NewsItem-author">...</div>
<div class="NewsItem-description">...</div>
<a class="NewsItem-gotoSource" href="#">...</a>
</div>
</div>

Existen tres tipos de elementos en el HTML que forma parte de una vista, ya sea una plantilla o un componente:

  1. Contenedores. Su función es agrupar otros elementos.
  2. Elementos servidores de contenido. Imágenes, textos, vídeos, gráficos, etc.
  3. Controles.

Un tipo especial de elemento HTML es el de los formatos de texto. Es especial ya que normalmente nunca pertenecerá a la plantilla sino que irá incrustado dentro del contenido.

De acuerdo con la nomenclatura que proponemos, un contenedor no podrá llamarse header, sidebar, footer, panel, etc., sino que su nombre tendrá que representar su función dentro de la aplicación. Actions, UserList, Metadata, SecondaryInfo, CartSummary, FeaturedProducts...

¿Qué pasa con el CSS?

Quizás a estas alturas estarás preguntándote qué pasa con el CSS. Esto de las clases específicas, legibles y semánticas está muy bien, pero suena a que lo vamos a pagar caro con el CSS. Una de las ventajas del CSS es que podemos no ser tan específicos, podemos afectar a un montón de elementos sin tener que definir las reglas para cada uno de ellos.

Be patient, my dear reader.

Una de las ideas para mantener un CSS sencillo, legible y controlable es aprovechar las capacidades de los preprocesadores actuales, pero esta vez para el bien.

Cuando tenemos un componente del tipo:

<a class="Login-submit"></a>

En el CSS podemos contar con:

.Login-submit {
@extend .Button--big
}

Y:

.Button {
.display: inline-block;
background-color: black;
color: white;
font-weight: bold;
padding: 1rem 2rem;
}
.Button--big {
@extend .Button;
padding: 1.5rem 3rem;
font-size: 1.4rem;
}

Por comodidad, está bien trocear el CSS