Los inicios
A principios de siglo, llamar desde un móvil de medio kilo de peso costaba 300 pesetas el minuto, una televisión de 32 pulgadas era escandalosamente grande y hacían falta dos paisanos grandes para moverla, los monitores de los ordenadores eran de 14 pulgadas y se maquetaba con tablas y estilos en línea.

La especificación 1 de CSS ya se había publicado en 1996 y la 2 en 1998, pero nada impedía que cometiéramos actos delictivos como éste:
<body bgcolor="#f0f0f0" text="#000000" link="#0000ff" vlink="#800080" alink="#ff0000">
<h1 align="center" face="Arial" color="#333333">Bienvenido a Mi Página Web</h1>
<hr noshade size="2" color="#cccccc">
<p align="justify" face="Verdana" size="2">
Este es un ejemplo de una página HTML4 que utiliza atributos para aplicar estilos.
Aquí puedes ver diferentes elementos HTML y cómo se pueden estilizar.
</p>
<h2 align="left" color="#006600">Sección 1: Listas</h2>
<ul>
<li color="#0000ff">Elemento de lista 1</li>
<li color="#0000ff">Elemento de lista 2</li>
<li color="#0000ff">Elemento de lista 3</li>
</ul>
<h2 align="left" color="#006600">Sección 2: Tabla</h2>
<table border="1" cellpadding="5" cellspacing="0" align="center" bgcolor="#ffffff">
<tr bgcolor="#cccccc">
<th color="#000000">Nombre</th>
<th color="#000000">Edad</th>
</tr>
<tr>
<td color="#000000">Juan</td>
<td color="#000000">25</td>
</tr>
<tr>
<td color="#000000">María</td>
<td color="#000000">30</td>
</tr>
</table>
<h2 align="left" color="#006600">Sección 3: Enlaces</h2>
<p>
Visita <a href="https://www.ejemplo.com" target="_blank">Ejemplo</a> para más información.
</p>
<h2 align="left" color="#006600">Sección 4: Imagen</h2>
<img src="https://via.placeholder.com/150" alt="Imagen de ejemplo" width="150" height="150" align="middle" border="0">
<h2 align="left" color="#006600">Sección 5: Formulario</h2>
<form action="#" method="post">
<label for="nombre" style="font-weight: bold;">Nombre:</label>
<input type="text" id="nombre" name="nombre" size="30" border="1">
<br><br>
<input type="submit" value="Enviar" bgcolor="#008000" text="#ffffff">
</form>
<hr noshade size="2" color="#cccccc">
<div align="center" size="2" color="#666666">
© 2023 Mi Página Web. Todos los derechos reservados.
</div>
</body>
Bonito ¿verdad? Evidentemente, esto era totalmente insostenible, y las buenas prácticas y también el sentido común recomendaban utilizar CSS por aquello de la limpieza, la reutilización, el mantenimiento y demás zarandajas. Utilizando CSS mantendríamos la consistencia de los estilos compartiendo los archivos CSS entre distintos documentos HTML, tendríamos nuestro código más legible y sería mucho más fácil de mantener. El engendro anterior pasaría a ser algo así:
/* styles.css */
.body {
background-color: #f0f0f0;
color: #000000;
}
.header {
text-align: center;
font-family: Arial, sans-serif;
color: #333333;
}
.subheader {
color: #006600;
}
.paragraph {
text-align: justify;
font-family: Verdana, sans-serif;
font-size: 14px;
}
.list-item {
color: #0000ff;
}
.table {
border-collapse: collapse;
margin: auto;
background-color: #ffffff;
}
.table-header {
background-color: #cccccc;
color: #000000;
}
.table-data {
color: #000000;
}
.link {
color: #0000ff;
}
.footer {
text-align: center;
font-size: 12px;
color: #666666;
}
.input-text {
border: 1px solid #000000;
}
.input-submit {
background-color: #008000;
color: #ffffff;
}
hr {
border: none;
height: 2px;
background-color: #cccccc;
}
img {
display: block;
margin: 0 auto;
}
table {
border: 1px solid #000000;
}
td, th {
padding: 5px;
}
<body class="body">
<h1 class="header">Bienvenido a Mi Página Web</h1>
<hr>
<p class="paragraph">
Este es un ejemplo de una página HTML4 que utiliza CSS para aplicar estilos.
Aquí puedes ver diferentes elementos HTML y cómo se pueden estilizar.
</p>
<h2 class="subheader">Sección 1: Listas</h2>
<ul>
<li class="list-item">Elemento de lista 1</li>
<li class="list-item">Elemento de lista 2</li>
<li class="list-item">Elemento de lista 3</li>
</ul>
<h2 class="subheader">Sección 2: Tabla</h2>
<table class="table">
<tr>
<th class="table-header">Nombre</th>
<th class="table-header">Edad</th>
</tr>
<tr>
<td class="table-data">Juan</td>
<td class="table-data">25</td>
</tr>
<tr>
<td class="table-data">María</td>
<td class="table-data">30</td>
</tr>
</table>
<h2 class="subheader">Sección 3: Enlaces</h2>
<p>
Visita <a href="https://www.ejemplo.com" target="_blank" class="link">Ejemplo</a> para más información.
</p>
<h2 class="subheader">Sección 4: Imagen</h2>
<img src="https://via.placeholder.com/150" alt="Imagen de ejemplo">
<h2 class="subheader">Sección 5: Formulario</h2>
<form action="#" method="post">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" class="input-text" size="30">
<br><br>
<input type="submit" value="Enviar" class="input-submit">
</form>
<hr>
<div class="footer">
© 2023 Mi Página Web. Todos los derechos reservados.
</div>
</body>
¿Qué nos ofrece esta segunda versión? Un código HTML mucho más limpio, separado por completo de los estilos. Estos estilos se pueden utilizar en múltiples documentos HTML, con lo que los escribimos una sola vez y podemos seguir ampliando estilos según vayamos necesitando. También podemos dividir el archivo CSS en varios ficheros según nuestras necesidades. Además, podemos hacer cambios en los estilos sin necesidad de modificar ningún documento HTML.
Los preprocesadores CSS
La adopción de CSS sin duda alguna supuso una mejora enorme a la hora de facilitar la creación de código legible y fácilmente mantenible, pero presentaba algunas carencias como podría ser el uso de variables y funciones. Es cuando surgen los preprocesadores CSS.
Los preprocesadores ofrecen la posibilidad de crear variables, funciones, anidamiento de selectores, reutilización de bloques de código mediante los denominados mixins, etc. Con el uso de preprocesadores CSS se daba un paso adelante en la legibilidad, mantenimiento y reutilización de estilos. Una auténtica maravilla.
Nuestro anterior archivo CSS podría pasar a tener este aspecto utilizando SASS:
// Variables
$background-color: #f0f0f0;
$text-color: #000000;
$header-color: #333333;
$subheader-color: #006600;
$list-item-color: #0000ff;
$table-header-bg: #cccccc;
$table-data-color: #000000;
$link-color: #0000ff;
$footer-color: #666666;
$input-border-color: #000000;
$input-submit-bg: #008000;
$input-submit-color: #ffffff;
$hr-color: #cccccc;
$table-border-color: #000000;
$padding: 5px;
// Mixins
@mixin center {
display: block;
margin: 0 auto;
}
@mixin text-style($font-family, $font-size, $color) {
font-family: $font-family;
font-size: $font-size;
color: $color;
}
.body {
background-color: $background-color;
color: $text-color;
}
.header {
@include text-style(Arial, inherit, $header-color);
text-align: center;
}
.subheader {
color: $subheader-color;
}
.paragraph {
@include text-style(Verdana, 14px, inherit);
text-align: justify;
}
.list-item {
color: $list-item-color;
}
.table {
border-collapse: collapse;
@include center;
background-color: #ffffff;
}
.table-header {
background-color: $table-header-bg;
color: $text-color;
}
.table-data {
color: $table-data-color;
}
.link {
color: $link-color;
}
.footer {
@include center;
font-size: 12px;
color: $footer-color;
}
.input-text {
border: 1px solid $input-border-color;
}
.input-submit {
background-color: $input-submit-bg;
color: $input-submit-color;
}
hr {
border: none;
height: 2px;
background-color: $hr-color;
}
img {
@include center;
}
table {
border: 1px solid $table-border-color;
}
td,
th {
padding: $padding;
}
Ya no tendremos que hacer búsquedas por tal o cual color para cambiarlo en todas partes ni repetir una y otra vez los mismos bloques de código para definir una tipografía, entre otras cosas. La potencia de los preprocesadores CSS sale a relucir especialmente en proyectos grandes y complejos.
Las capas de utilidad y el enfoque utility first
En el ámbito de los estilos CSS podemos hablar de capas de utilidad cuando tenemos clases altamente reutilizables que aplican una única propiedad o una serie de propiedades muy pequeña. De este modo, podemos tener, por ejemplo, una clase denominada .bg-red y así aplicar un color rojo de fondo a cualquier elemento. Son muy útiles cuando se necesita modificar una propiedad concreta de un elemento sin necesidad de escribir una clase nueva específica para él.
El problema de esta forma de trabajar es que se nos puede ir fácilmente de las manos cuando hacemos recaer todos los estilos en clase de utilidad. Este enfoque es lo que se conoce como utility first, donde creamos una clase CSS prácticamente por cada propiedad. Así, si queremos algo como esto:

Nuestro código, siguiendo el enfoque utility first quedaría más o menos de esta manera:
.w-300 {
width: 300px;
}
.h-300 {
height: 300px;
}
.bg-blue {
background-color: #1e4fcb;
}
.text-white {
color: #fff;
}
.font-arial {
font-family: Arial, Helvetica, sans-serif;
}
.text-lg {
font-size: 1.2rem;
}
.border-4 {
border-width: 4px;
}
.border-solid {
border-style: solid;
}
.border-blue {
border-color: #071a4c;
}
.rounded-5 {
border-radius: 5px;
}
.flex {
display: flex;
}
.justify-center {
justify-content: center;
}
.items-center {
align-items: center;
}
<div class="w-300 h-300 bg-blue text-white font-arial text-lg border-4 rounded flex justify-center items-center">
<p>Lorem ipsum</p>
</div>
Claro, no tiene mucho sentido escribirnos todas las clases de utilidad en cada proyecto, así que nos las vamos llevando de proyecto en proyecto y añadiendo lo que vayamos necesitando para cada uno. Pero, evidentemente, es poco práctico y bastante pesado.
Entonces llegó Tailwind. Tailwind es un framework CSS que nos da toda una serie de clases de utilidad listas para usar. Más de 4000 clases me chiva ChatGPT. Ideal para dar estilos sin saber CSS. Óptimo para no tener que escribir ni una línea de CSS. El framework de cabecera para esos youtubers que te hacen un clon de Netflix (😂) en media hora y que no se quieren parar a escribir estilos. ¡Albricias! ¡Ya no tengo que aprender CSS! ¡Sólo con la referencia de Tailwind ya puedo hacer interfaces supermolonas!
La aberración
Espera, no tan deprisa. Algo de CSS tendrás que saber porque si no muchos nombres de clases no sabrás muy bien para qué sirven. Y bueno, teniendo en cuenta que solo hay 618 propiedades CSS, a priori no parece tan buen negocio, pero bueno, qué sabré yo.
Dicho esto, nuestro HTML del ejemplo inicial quedaría de la siguiente manera utilizando el poder de Tailwind:
<body class="bg-gray-100 text-black">
<h1 class="text-center text-3xl font-sans text-gray-800">Bienvenido a Mi Página Web</h1>
<hr class="border-0 h-2 bg-gray-300" />
<p class="text-justify font-serif text-base">
Este es un ejemplo de una página HTML4 que utiliza Tailwind CSS para aplicar estilos. Aquí
puedes ver diferentes elementos HTML y cómo se pueden estilizar.
</p>
<h2 class="text-left text-2xl text-green-700">Sección 1: Listas</h2>
<ul class="list-disc pl-5">
<li class="text-blue-600">Elemento de lista 1</li>
<li class="text-blue-600">Elemento de lista 2</li>
<li class="text-blue-600">Elemento de lista 3</li>
</ul>
<h2 class="text-left text-2xl text-green-700">Sección 2: Tabla</h2>
<table class="border-collapse mx-auto bg-white border border-black">
<tr>
<th class="bg-gray-300 text-black p-2">Nombre</th>
<th class="bg-gray-300 text-black p-2">Edad</th>
</tr>
<tr>
<td class="text-black p-2">Juan</td>
<td class="text-black p-2">25</td>
</tr>
<tr>
<td class="text-black p-2">María</td>
<td class="text-black p-2">30</td>
</tr>
</table>
<h2 class="text-left text-2xl text-green-700">Sección 3: Enlaces</h2>
<p>
Visita
<a href="https://www.ejemplo.com" target="_blank" class="text-blue-600">Ejemplo</a> para más
información.
</p>
<h2 class="text-left text-2xl text-green-700">Sección 4: Imagen</h2>
<img src=“https://placehold.org/150x150/3399ff" alt="Imagen de ejemplo" class="block mx-auto" />
<h2 class="text-left text-2xl text-green-700">Sección 5: Formulario</h2>
<form action="#" method="post" class="mb-4">
<label for="nombre" class="block">Nombre:</label>
<input type="text" id="nombre" name="nombre" class="border border-black p-2 mb-2" size="30" />
<br />
<input type="submit" value="Enviar" class="bg-green-700 text-white p-2" />
</form>
<hr class="border-0 h-2 bg-gray-300" />
<footer class="text-center text-sm text-gray-600">
© 2023 Mi Página Web. Todos los derechos reservados.
</footer>
</body>
Un momento, aquí pasa algo raro. ¿Por qué se me está apeteciendo arrancarme los ojos? ¿Nos hemos subido sin darnos cuenta en un DeLorean y nos hemos ido 30 años atrás en el tiempo? ¿No se parece demasiado al primer ejemplo sin CSS?
Utilizando el enfoque utility first de Tailwind, lo que estamos haciendo es directamente a cada elemento añadirle una clase por cada propiedad CSS que queramos personalizar, es decir, hacer exactamente lo mismo que hacíamos antes de la existencia de CSS, y convirtiendo nuestro código en algo bastante ilegible, sucio e inmantenible.
Para resolver este desaguisado, a las brillantes mentes detrás de Tailwind decidieron sacar la directiva @apply, y así hacer el código un poco más mantenible y limpio. ¿En qué consiste? Bueno, para verlo nada mejor que un ejemplo. El código de nuestro div azul con texto blanco centrado que vimos más arriba para explicar las clases de utilidad tendría este aspecto si utilizamos Tailwind:
<div class="w-[300px] h-[300px] bg-[#1e4fcb] text-white font-sans text-lg border-4 border-[#071a4c] rounded flex justify-center items-center">
<p>Lorem ipsum</p>
</div>
Claro, esta docena de clases dificulta un pelín la legibilidad y el mantenimiento, con lo que usaremos la directiva @apply:
.my-stunning-tailwind-class {
@apply w-[300px] h-[300px] bg-[#1e4fcb] text-white font-sans text-lg border-4 border-[#071a4c] rounded flex justify-center items-center;
}
<div class=“my-stunning-tailwind-class”>
<p>Lorem ipsum</p>
</div>
Ah, claro, tiene sentido, gran solución. Así agrupamos todo en una clase, incluimos el CSS y ya nos queda todo mucho más limpio y mantenible.

Pero vamos a ver. ¿NO ES ESO EL PRINCIPIO DE TODO? ¿Qué sentido tiene usar un framework CSS para no tener que escribir CSS y luego tener que agrupar las clases de ese framework en nuestras propias clases CSS? ¿Por qué no nos ahorramos todo esto y utilizamos directamente CSS?
Vivimos tiempos extraños: cerveza y ginebra sin alcohol, hamburguesas a precio de solomillo y frameworks que vienen a solucionar problemas que no existen creando otros que ya estaban solucionados.. Skynet, despierta ya y acaba con todo este sinsentido, por favor.
Si te quedaste con ganas, hay más madera en secture.com/blog