Tu código CSS es una mierda.

Es probable que sea un confuso y frágil.

Pero estate tranquilo, porque no es culpa tuya.

Al escribir CSS es natural que se vuelva complejo y enrevesado.

Te voy a contar cómo puedes simplificar tu CSS con tan solo 3 conceptos en los que se apoyan gigantes del desarrollo web como LinkedIn o Twitter.

Apuesto a que esta historia te va a sonar de algo:

Acabas de empezar un nuevo proyecto y tienes que desarrollar una página web. Los diseñadores se han empleado a fondo para crear la parte visual de una web súper bonita… ¡y encima parece fácil de programar!

Abres tu editor de código y empiezas a picar HTML como si no hubiera mañana: menú de navegación, cabecera, el contenido principal, pie de página y unos botoncitos para las redes sociales. ¡Esto está chupao’! -piensas.

Entonces es cuando llega la hora de darle ese aspecto visual tan molón que se ha currado la gente de diseño: es la hora del CSS.

Le pones un identificador al menú para poder darle estilo… unas clases de Bootstrap por aquí para hacer un grid… una clase para este botón… ¡Vaya! Parece que en esta parte de la página hay otro botón pero es un pelín distinto… no pasa nada, otro id distinto y listo.

Al día siguiente abres el proyecto y resulta que tu compañero de trabajo ha avanzado bastante y el diseño de la página está casi terminado. ¡Perfecto! Menos trabajo para mí -piensas- y continúas dando los estilos que faltan.

De repente te das cuenta de que algo no está bien, resulta que un texto aparece en azul en lugar de negro, tu compañero ha metido la gamba… ¡pero vaya fallo más tonto! Buscas por toda la hoja de estilo y localizas dónde puede estar el error. Cambias el color del texto, refrescas la página y…

Han cambiado de color otros cinco textos que no querías cambiar y el que te interesaba sigue igual que antes. Revisas la línea que has cambiado, intentas descifrar el selector que usó tu compañero:

#hero-section ul > li input:checked + label:hover

Entornas los ojos, te alejas de la pantalla, respiras profundamente e intentas adivinar qué cojones es eso…

Haces el truqui infalible súper secreto…

color: black !important;

Pero nada, todo sigue igual. 20 minutos más tarde sigues sin conseguir cambiar el color del puñetero texto… ¡En qué estaría pensando tu compañero cuando lo programó! ¡¡Esto no hay quién lo arregle!!

¿Te resulta familiar?

Es normal, todos nos hemos enfrentado a esta situación en un momento u otro. Es un problema muy común, sobre todo cuando trabajamos en equipo y cada miembro tiene una manera distinta de escribir CSS, o cuando usamos bibliotecas externas como Bootstrap, Normalize, Materialize, etc.

Darle CSS a un programador es como darle una escopeta a un Borbón: lo mejor que puede pasar es que se dispare en el pié.

¿A qué se debe esto? Hay dos causas principales:

  1. Falta de una convención

En CSS no existe ninguna regla para crear selectores. Puedes usar IDs, clases, poner estilo inline o usar las propias etiquetas HTML para aplicar tus estilos. Además cada desarrollador puede definir esos nombre como quiera. Por ejemplo lo que uno llama #lista-desplegable otro lo puede llamar .customList y otro lo puede llamar ul, cuando están intentando referirse a lo mismo.

  1. No comprender cómo funciona la especificidad

CSS tiene un mecanismo bastante complejo para decidir qué estilos deben tener prioridad por encima de otros. La mayoría de desarrolladores no comprende cómo funciona.

CSS asigna una puntuación a cada selector para determinar cuál tiene prioridad sobre otro. Esta puntuación se calcula en función de tres factores:

  • El número de identificadores: cada id vale 100 puntos
  • El número de clases: cada clase vale 10 puntos
  • El número de tags HTML: cada uno vale 1 punto

Se entiende fácil con un ejemplo:

Ejemplo de selector CSSNúmero de #IDsNúmero de .clasesNúmero de <tags>Puntuación de especificidad
p0011
.contenido01010
#header100100
div p0022
.titulo.principal02020
#header img101101

Hay un par de excepciones a esta norma:

  1. Los estilos en línea (los que se declaran en el atributo style de un elemento) tienen prioridad sobre los estilos definidos en las hojas de estilo CSS.
  1. Los estilos que usan !important tienen prioridad sobre todos los demás.

Por esta razón casi nunca es recomendable usar estilos en línea ni !important, porque hacen que el código sea más difícil de entender y modificar. Además, ¿qué pasa si dos selectores utilizan !important? Que estás como al principio: el resto de factores de prioridad serán los que determinen qué estilo se impone.

Solución

Para evitar estos problemas, es necesario utilizar una convención, es decir, un conjunto de reglas que los desarrolladores deben usar de forma consistente a modo de “guía” para evitar estas situaciones problemáticas.

Por suerte, en los últimos años han surgido varias arquitecturas, métodos que pretenden darnos una estructura predeterminada que nos ahorrará tiempo a la hora de implementar nuestros estilos web.

Las tres metodologías más comunes son: OOCSS, SMACSS y BEM, todas ellas establecen normas de uso de CSS, que limitan la toma de decisiones que tendremos que hacer y nos ayudan a seguir algún tipo de patrón.

Cómo funcionan las metodologías CSS

OOCSS: CSS orientado a objetos

Esta metodología es la más básica de todas, tiene pocas restricciones:

  • Sólo se utilizan selectores de clase en nuestro código CSS (ej: .cabecera). No se usan selectores de #id ni nombres de etiquetas HTML. Usando solo clases se consigue que todo el código CSS sea reutilizable.
  • Una web estará compuesta por dos tipos de estilos: los elementos que definen la estructura de la página y los “skins” que agrupan estilos compartidos por varios elementos.

SMACSS: Arquitectura Escalable y Modular para CSS

Es una versión evolucionada y sofisticada del CSS orientado a objetos. En lugar de diferenciar sólo entre elemento y skin, se clasifican las partes del estilo en 5 categorías: base, layout, modules, states y themes.

Las ventajas de BEM: Bloque, Elemento, Modificador

El CSS orientado a objetos es demasiado simple y tiende a producir código caótico, los nombres de las clases pueden ser cualquier cosa y se confunden entre sí los elementos y sus skins.

SMACSS está en el extremo opuesto: es una metodología demasiado compleja, utiliza multitud de categorías para clasificar los elementos, y eso la hace difícil de aplicar en la práctica.

La metodología BEM queda a medio camino entre OOCSS y SMACSS, combina lo mejor de cada mundo:

  • Se usan clases para reutilizar el código y des-acoplarlo del HTML
  • Sólo hay 3 conceptos: bloques, elementos y modificadores, por tanto es rápido de aprender y fácil de aplicar
  • Fuerza componentización y nombres consistentes

BEM es la metodología que escogen grandes medios de Internet como son The Guardian, BBC News o LinkedIn. Todos ellos requieren de sistemas de diseño completos, que permitan reutilizar y mantener el código ordenado de forma sencilla.

Cómo funciona

En BEM, definiremos todos nuestros estilos utilizando solo clases y pseudo-selectores. Queda prohibido usar #identificadores o nombres de etiquetas HTML en nuestro CSS.

Además, todos los nombres de las clases van a seguir una misma estructura:

.bloque__elementomodificador

A continuación veremos qué significa eso de bloque, elemento y modificador, y cómo vamos a nombrar nuestras clases.

El primer paso es hacer una análisis del diseño y dividir la página en partes más pequeñas para ordenar nuestro código y evitar repetirnos.

Bloques: las partes independientes

Llamaremos bloque a un pedazo de nuestra página web que tiene sentido por sí mismo.

Para declarar los estilos de los bloques utilizaremos sencillamente una clase con el nombre del bloque, por ejemplo: .cabecera

A veces, los bloques pueden tener nombres compuestos por varias palabras. En este caso usaremos guiones en nuestra clase, por ejemplo: .mi-bloque-compuesto

Veamos algunos ejemplos típicos de bloques:

Un botón

Este es el ejemplo más típico de bloque. Un botón tiene sentido por sí mismo y podría reutilizarse en otras pantallas:

Podríamos darle estilo en CSS con la clase .button y usarlo en HTML como:

<button class=”button”>Twitter</button>

Un post de una red social

Los bloques no tienen por qué ser siempre tan sencillos como un botón, también pueden existir bloque más complejos, como por ejemplo los posts (publicaciones) que aparecen en los feeds de la redes sociales.

Si te paras a pensarlo los posts son también trozos de página que se reutilizan y que tienen sentido por sí mismos.

Podríamos dar estilo a este bloque con la clase .post y usarlo en HTML como:

<article class=”post”> … </article>

Un menú de navegación

Otro ejemplo de bloque muy común es el menú de navegación, una parte que se suele reutilizar en todas las páginas de un website:

A este bloque podríamos darle estilo con la clase .menu y usarla en el HTML como:

<nav class=”menu”>…</nav>

En resumen, los bloques pueden ser más o menos complejos, pero siempre se caracterizan por ser partes de la página web que se pueden reutilizar y que son independientes del resto.

En caso de que quisiéramos usar un nombre compuesto para hacer referencia a un bloque, podríamos hacerlo utilizando guiones para separar las palabras en nuestra clase, por ejemplo: .main-menu o .hero-section

Elementos: las distintas partes de un bloque

Llamamos elemento a un trozo de nuestra página que no tiene sentido por sí solo, sino que siempre formará parte de un bloque.

Un elemento es una parte de un bloque. De esta manera un bloque podrá contener uno o varios elementos.

Para declarar los estilos de los elementos utilizaremos clases con esta estructura:

.bloque__elemento

Como ves el nombre de la clase combina el nombre del elemento con el nombre del bloque al que pertenece.

Veamos algunos ejemplos de elementos:

Las distintas opciones de un menú

Siguiendo con el ejemplo anterior, habíamos dicho que un menú de navegación podría ser un bloque, que tendría la clase .menu, pero, ¿qué clases usaríamos para referirnos a cada una de sus partes? Como vemos contiene un logo y seis botones:

Siguiendo la estructura que hemos visto podríamos dar estilo al elemento logo usando la clase .menu__logo y a los elementos botones usando la clase .menu__button, de modo que el HTML quedaría parecido a esto:

<nav class=”menu”>

<svg class=”menu__logo”>…</svg>

<button class=”menu__button”>Join</button>

<button class=”menu__button”>Log in</button>

<button class=”menu__button”>Pricing</button>

<button class=”menu__button”>Features</button>

<button class=”menu__button”>Inspiration</button>

<button class=”menu__button”>Stock</button>

</nav>

Las distintas partes de una sección

Retomemos el ejemplo de antes, un bloque .post que muestra una publicación.

Observemos que este bloque que contiene varios elementos: una imagen, una título, botones… etc.

Podríamos hacer referencia a esos elementos siguiendo la estructura que ya conocemos:

.post__image

.post__title

.post__buttons

Por tanto, nuestro HTML quedaría parecido a esto:

<article class=”post”>

<img class=”post__image”></img>

<h2 class=”post__title”>Apple makes over $3 every time someone…</h2>

<button class=”post__title>Like</button>

<button class=”post__title>Like</button>

<button class=”post__title>Share</button>

</article>

Errores comunes al nombrar elementos

Cuidado, es fácil equivocarse al nombrar elementos y complicar las cosas más de la cuenta. Ten cuidado con estos casos:

⚠️ Confundir bloque con elemento

Ante la duda, pregúntate: ¿este trozo de mi página web se podría usar por sí mismo? Si es así se trata de un bloque. Si ese trozo depende de otro o no tiene sentido por sí mismo, probablemente sea un elemento.

⚠️ Anidar cuando no es necesario

En BEM no existe el concepto de “sub-elementos”, es decir, un bloque puede contener elementos, pero un elemento no puede contener más sub-partes. Por tanto no existen clases del estilo .bloque__elemento__subelemento, en su lugar, lo que se hace es simplemente crear un nuevo bloque, aunque esto no suele ser necesario.

Imagina que tienes este bloque como este, que representa una publicación destacada de un periódico, que contiene una sección con un párrafo de texto y una imagen, y debajo una etiqueta con el autor:

<article class=”featured-post”>

<div class=”featured-post__content”>

<img src=”…”></img>

<p>…</p>

</div>

<span class=”featured-post__author”>…</span>

<article>

¿Qué clases podríamos usar para referirnos a la imagen y el texto?

No tendría sentido sacarlos a un componente aparte porque no tendrían sentido por sí solos, por lo que simplemente podemos referirnos a ellos con las clases: .featured-post__text y .featured-post__picture

Recuerda: en BEM no es necesario que los nombres de los elementos estén anidados de la misma manera que el HTML.

Modificadores: aliña tus bloques y componentes

Los modificadores son clases puedes añadir para cambiar la apariencia o el comportamiento de los bloques y elementos.

Los  modificadores se utilizan normalmente para diferenciar las distintas variantes de un bloque o un elemento.

Para modificar un bloque usaremos clases con la estructura .bloque–modificador y para modificar un elemento usaremos .bloque__elemento–modificador

Por ejemplo, si tenemos dos botones, uno primario y otro secundario:

Usaremos modificadores para diferenciarlos:

<button class=”button button–primary”>

Primary

</button>

<button class=”button button–secondary”>

Secondary

</button>

Otro ejemplo típico es usar modificadores para controlar el tamaño de los textos:

Título normal

Título grande

Podríamos implementarlos como:

<h1 class=”title title–size-regular”>

Título normal

</h1>

<h1 class=”title title–size-big”>

Título grande

</h1>

⚠️Nunca uses solo modificadores

Las clases modificador siempre deben acompañar a una clase bloque o una clase elemento, no tiene sentido que aparezcan solas:

Esto está mal 👎

<button class=”button–primary”></button>

<button class=”menu__button–primary”></button>

Esto está bien 👍

<button class=”button button–primary”></button>

<button class=”menu__button menu__button–primary”></button>

En conclusión, la metodología BEM nos ayuda a simplificar nuestro CSS y conseguir un estilo consistente, por lo que nuestro código será mucho más legible y será más fácil de mantener.