Déjame que te explique el motivo de porqué prefiero PostCSS, y tú también deberías, para escribir CSS.
Disclaimers
- Lo que leerás aquí es mi opinión, basada en mis experiencias y mi punto de vista, por lo que estoy abierto a recibir cualquier tipo de feedback constructivo.
- Soy consciente de que aunque te convenza, puede ser que no tengas la oportunidad de utilizar PostCSS en el proyecto que estés trabajando. Sin ir más lejos, en Adevinta Spain Engineers estamos utilizando Sass (estoy trabajando en una propuesta para pasarnos a PostCSS 🤪*)* y hay varias preferencias entre nosotras/os.
- No se trata de un tutorial paso a paso de cómo instalar, configurar y utilizar PostCSS.
Origen de los Preprocesadores CSS
Empecemos por repasar el origen de los Preprocesadores CSS.
Un preprocesador CSS es un programa que te permite generar CSS a partir de la sintaxis única del preprocesador.
El primero de ellos (que yo recuerde) fue Less una librería JavaScript que nos ofrecía una nueva sintaxis, que después de parsear nuestro código, lo convertía en CSS soportado por los navegadores. Como Less, aparecieron otras herramientas, como Sass, Stylus o PostCSS.
Con estas nuevas herramientas, y su nueva sintaxis (sobre CSS), de repente teníamos en nuestras manos un lenguaje de programación con variables, funciones, mixins, bucles u operadores. Con ello podíamos reaprovechar mucho código, tanto en el mismo proyecto, como entre varios proyectos. La punta de lanza fueron las variables, sin saberlo, apareció la base de lo que ahora conocemos como Tokens de los actuales sistemas de diseño. Todo un sueño para cualquier programador/a.
Qué creo que asusta de PostCSS
Recientemente un amigo me comentaba:
Aún no me he puesto con PostCSS. Lo intenté hace unos años en un proyecto a raíz de la charla de Naiara Abaroa, y lo sufrí mogollón. Y me volví a mi cómodo SCSS.
Por una parte, entiendo lo que le pasó a Alberto, al principio PostCSS puede asustar. Pero me sorprende el comentario de que SCSS lo encuentre cómodo, ya que en su momento tuvo que aprender una nueva sintaxis, nada que ver con el CSS estándar.
Hola PostCSS
La primera apreciación al acercarte a PostCSS es que es un caos. Muchos parámetros de configuración, muchas maneras de hacer las cosas, muchos plugins, el orden de configuración de esos plugins importa, ya que puede variar el resultado y lo más chocante, no esperes encontrarte con un sistema de errores de sintaxis CSS, ya que puedes inventar cualquier propiedad, alias o sintaxis y que tu propio plugin genere el CSS que necesitas.
Algo así como los @mixins
de Sass, pero menos controlado, ya que toda la validación recae en la persona que desarrolla el plugin que transformará ese código en lo deseado, sino, lo devolverá tal cual. Y claro, puede ser una sintaxis que no tenga ningún sentido para el navegador.
Seguro que si te estabas planteando salir de esa zona de confort que te ha ofrecido Sass durante tanto tiempo, te acabo de asustar. Pero ten un poco de paciencia, recuerda que explico esto porque es lo que creo que asusta a la gente a pasarse a PostCSS.
PostCSS conviviendo con nuestro proyecto en Sass
Una de las primeras preguntas que aparecen cuando nos decidimos a probar o implementar PostCSS en nuestro proyecto activo es:¿Es necesario cambiar todo Sass a PostCSS o pueden convivir?, pueden convivir, de hecho lo más seguro es que ya estés utilizando PostCSS sin saberlo.
Si estás utilizando Autoprefixer en tu proyecto, ya estás utilizando PostCSS. Ya que se trata del plugin impulsor de todo este ecosistema PostCSS.
Hay varias maneras de hacer convivir PostCSS y Sass (u otro preprocesador), si estás usando Autoprefixer, lo estarás ejecutando después de generar el CSS desde Sass, para añadir los prefix vendors necesarios. Es en ese punto donde puedes añadir plugins de optimización como: cssnano, CSS MQPacker, Sort Media Queries, que son plugins que optimizan el CSS generado por Sass.
Así que en este caso estaríamos utilizando Sass para desarrollar nuestro CSS y PostCSS para optimizarlo.
Existe el plugin PostCSS SCSS Syntax, el cual te permite escribir la sintaxis de SCSS pero utilizar el ecosistema PostCSS para generar el CSS final.
Hay muchos plugins, te animo a que eches un vistazo a PostCSS.parts y PostCSS Plugins donde encontrarás muchos de ellos, agrupados por categorías. Eso sí, te aconsejo que si encuentras uno que te interesa y es un pack de plugins, como los que encontrarás en packs, primero analices qué plugins incluye, qué plugins necesitas y valorar utilizarlos por separado. Esto te permitirá tener el control y obligarte a leer la documentación de cada uno de ellos. En esa lista verás que está postcss-preset-env, del que hablaré más adelante.
Aprovecho para comentarte que recientemente he publicado un plugin PostCSS que permite utilizar el nuevo formato de imágenes AVIF en las imágenes de background de nuestro CSS, avif-in-css. Deja una ⭐️ si crees que es interesante, ver que tengo el apoyo de la gente me anima a crear más herramientas 😊. En este artículo explico cómo utilizarlo AVIF in CSS con PostCSS.
¿Quién está utilizando PostCSS?
Aquí es donde podría listar una larga lista de nombres de empresas muy conocidas, pero prefiero profundizar un poco más y ver que está incluido en frameworks que se están utilizando en muchos proyectos en producción.
Empecemos por el framework CSS más conocido de todos Bootstrap, si echamos un vistazo al package.json veremos que entre las dependencias se encuentra PostCSS.
Aquí podemos ver que Bootstrap está utilizando PostCSS para gestionar el tema de LTR (Left To Right) para dar cobertura al contenido que tiene este formato de lectura, y con Autoprefixer añadir los prefix vendors necesarios.
#nuclitip
analizar las dependencias de herramientas, frameworks o aplicaciones, me ayuda a entender mejor qué hay detrás de ellas. Y en muchas ocasiones descubrir qué magia se esconde tras ciertas funcionalidades.
Otro de los frameworks que actualmente está entre los trending topics es Tailwind CSS, que con un paradigma totalmente opuesto al que hemos estado utilizando durante mucho tiempo, nos ofrece una serie de utilidades para aplicar nuestros estilos con un patrón de composición desde nuestro HTML, el próximo artículo lo quiero dedicar a compartir mi opinión sobre este framework.
Pues en este caso, PostCSS está presente en el 100% de Tailwind CSS, ya que no está utilizando Sass, Less o Stylus en la codificación de las propiedades CSS.
La primera versión se basó en suitcss-base que incluye suitcss-preprocessor como preprocesador, que está formado por varios plugins PostCSS.
Así que estamos utilizando PostCSS en muchos de los frameworks CSS que se están utilizando en los desarrollos web.
PostCSS escribiendo CSS estándar y de próxima generación
Aquí conocerás el motivo de más peso por el que prefiero PostCSS, no es porque es chulo, porque el lenguaje detrás de los plugins es JavaScript, no es porque me hace parecer un super cool developer, es porque me permite escribir CSS estándar.
Como su propia definición nos informa, PostCSS es una herramienta para transformar CSS con Javascript. Eso quiere decir que podemos escribir cualquier sintaxis en un archivo CSS y mediante un plugin, convertirlo para que el CSS resultante lo puedan interpretar los navegadores.
Bajo esa premisa, Max Thirouin le dió un enfoque muy interesante, en lugar de inventar sintaxis, utilizar los plugins para poder escribir el CSS que se está definiendo en la CSSWG de la W3C, y que esos plugin conviertan el CSS “del futuro” en CSS que funcione en los navegadores actuales.
CSSNEXT
De esa idea salió cssnext, un pack de plugins PostCSS que seguían de cerca los borradores de la CSSWG para mentener actualizados los plugins. El proyecto apareció en agosto de 2014, siendo actualizado prácticament de forma mensual hasta enero de 2018 y en mayo del mismo año Max publicaba el artículo Deprecating cssnext, donde expresaba su opinión de no estar de acuerdo con las direcciones que estaba tomando PostCSS y que ya no estaba trabajando con CSS directamente, eso sí, en el mismo artículo nos aconsejaba utilizar postcss-preset-env de Jonathan Neal.
I tried to maintain the package for a while, as the number of downloads prove that people are actually using it. But now that a solid alternative is around (postcss-preset-env), I think it’s time to deprecate cssnext.
postcss-preset-env
Como ya comenté en PostCSS Preset Env, el Babel de CSS, utilizar PostCSS con postcss-preset-env nos abre las puertas a utilizar las propiedades que se están definiendo en la CSSWG antes de que lleguen a estar implementadas en los navegadores, no todas claro.
Sí, este paquete es un pack de plugins, así que recuerda, úsalo con conocimiento y estudiando la documentación de los plugins que vayas a utilizar.
Al tratarse de un pack de varios plugins la manera de especificar el soporte que queremos es mediante el estado de la especificación. Aquí Jonathan Neal planteó un sistema de estados igual que tenemos en JavaScript, así que en cssdb podemos consultar el estado de cada una de las propiedades CSS, así como información con enlaces a la documentación oficial de la especificación y el repositorio del plugin que podemos utilizar para utilizar esa nueva propiedad.
Aquí podemos ver un ejemplo de la información que podemos encontrar: estado, nombre, enlace a la especificación, enlace al plugin PostCSS y un ejemplo de código. Así es, tendremos nesting de forma nativa en CSS.
En esta otra imagen podemos ver los diferentes estados que tenemos disponibles. Así que si queremos utilizar nesting en nuestro código CSS, lo podemos hacer como si ya estuviera disponible en los navegadores.
postcss.config.js
...
plugins: [
postcssPresetEnv({
stage: 1
}),
]
...
style.css
article {
& p {
color: var(--color-text);
}
}
Con una configuración de stage: 1
postcss-prest-env parseará nuestro CSS utilizando los plugins necesarios para dar soporte a las especificaciones de estado 1 o superior. De esta forma, cuando nesting esté en stage 4
ya no se usará el plugin de nesting, ya que lo tendremos soportado de forma nativa.
Use tomorrow’s CSS today
Como el propio eslogan de postcss-preset-env nos indica, podemos utilizar sintaxis del mañana, hoy.
En muchas ocasiones hago referencia a escribir CSS estándar de forma errónea, ya que en otros preprocesadores también se puede escribir CSS estándar. Mi error está en llamarlo estándar y querer referirme a escribir una sintaxis de CSS que acabará en el estándar, ya que es parte de la especificación, pero en un estado de borrador o release candidate. Veamos unos ejemplos.
El siguiente código no está soportado por los navegadores actuales, pero lo estará, y es un código que no podemos escribir con preprocesadores como Sass, el cual no haría ningún tipo de transformación en el proceso de compilación.
image-set() function
Este sería nuestro código CSS que escribimos, para cargar una imagen u otra según la resolución del dispositivo. Lo mismo que podemos hacer con el tag <picture>
en HTML, pero directamente con las imágenes de background de nuestro CSS.
.example {
background-image: image-set(
url(img.png) 1x,
url(img@2x.png) 2x,
url(img@print.png) 600dpi
);
}
Esto lo podremos hacer de forma nativa (estándar) cuando tengamos soporte en todos los navegadores, como podemos ver en la especificación del módulo CSS Image.
El plugin que se encargará de transformar esté código a CSS que entiendan todos los navegadores es postcss-image-set-function y este sería el código de salida de nuestro ejemplo.
.example {
background-image: url(img.png);
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.example {
background-image: url(img@2x.png);
}
}
@media (-webkit-min-device-pixel-ratio: 6.25), (min-resolution: 600dpi) {
.example {
background-image: url(my@print.png);
}
}
.example {
background-image: image-set(
url(img.png) 1x,
url(img@2x.png) 2x,
url(img@print.png) 600dpi
);
}
Simplemente añadiría el fallback para dar soporte a los navegadores que lo necesite.
¿Os suena esto?, es el mismo escenario que tenemos en JavaScript. Transpiladores como Babel nos permiten escribir sintaxis como el Optiona Chaining y dar cobertura a Interner Explorer 11.
¿Pasará de moda PostCSS?
Personalmente, creo que no, PostCSS nos ofrece la oportunidad de utilizar o escribir plugins para optimizar nuestro CSS, para añadir linters (como stylelint), crear alias, o sintaxis muy personalizadas según el proyecto.
Si a eso añadimos *postcss-prest-env**, que está actuando como un transpilador de las nuevas funcionalidades, creo que PostCSS es el Babel para CSS. Siempre habrá alguna nueva propiedad para transpilar y dar soporte a navegadores que no tienen soporte para esa nueva propiedad.
Conclusiones
El simple hecho de poder escribir CSS estandar debería ser razón de peso como para, no plantearse si cambiar de Sass a PostCSS, sino para preguntarse, ¿porqué estamos escribiendo CSS en una sintaxis que no es la nativa?.
Soy un romántico de CSS, me gusta escribir CSS nativo, o Vanilla CSS como también se le llama. Es por eso que yo prefiero PostCSS, no por ser cool o parecer más developer, sino porque estoy escribiendo CSS. Así que siempre que me pregunten aconsejaré utilizar PostCSS con postcss-preset-env, ya sea a alguien que empieza a desarrollar, como alguien que lleva años con el desarrollo frontend.
Si os frena la curva de aprendizaje de la configuración de un entorno PostCSS, estad atentas/os, en breve anunciaré un curso para empezar con PostCSS desde cero, integrar PostCSS en un proyecto con Sass y cómo migrar un proyecto de Sass a PostCSS.