La herramienta invisible detrás de tu CSS
Si trabajas en desarrollo web, es muy probable que PostCSS ya esté procesando tus hojas de estilo aunque nunca lo hayas instalado de forma explícita. Frameworks y herramientas como Vite, Next.js, Angular CLI o Tailwind CSS lo usan internamente para añadir prefijos, transformar sintaxis moderna o minificar el resultado. Es una de esas piezas de infraestructura que funcionan tan bien que pasan desapercibidas.
PostCSS es una herramienta escrita en JavaScript que lee un archivo CSS, lo convierte en un árbol de sintaxis abstracta, lo entrega a una cadena de plugins que pueden modificarlo, y finalmente vuelve a generar CSS. Por sí solo no hace prácticamente nada: todo su poder proviene de los plugins que eliges. Esta arquitectura lo convierte en algo parecido a lo que Babel es para JavaScript, una plataforma para transformar CSS con plugins según las necesidades de cada proyecto.
En este tutorial veremos qué es PostCSS y en qué se diferencia de un preprocesador, cómo instalarlo y configurarlo, qué plugins resultan imprescindibles hoy, cómo integrarlo con la línea de comandos y con Vite, y cómo escribir un plugin propio. Trabajaremos con las versiones estables actuales:
- PostCSS 8.5, en concreto la versión 8.5.32.
- PostCSS CLI 11.0.
- PostCSS Preset Env 11.6.
- Autoprefixer 10.6.
- cssnano 7.1.
- Stylelint 17.
Varias de estas herramientas han cambiado de forma notable en los últimos años. Stylelint 17, por ejemplo, ya solo se distribuye como módulo ECMAScript y requiere Node.js 20.19 o superior, y el anidamiento de CSS ya es una característica nativa de los navegadores. Lo tendremos en cuenta en cada sección.
Qué es PostCSS y en qué se diferencia de Sass
La comparación más habitual es con preprocesadores como Sass, Less o Stylus. Aunque a menudo se usan para tareas parecidas, su filosofía es opuesta.
Un preprocesador define su propio lenguaje. Escribes en sintaxis de Sass, con sus variables, mixins y funciones, y el compilador la traduce a CSS. Todo lo que puedes hacer está determinado por las capacidades del lenguaje.
PostCSS, en cambio, no define ningún lenguaje. Recibe CSS, o algo muy parecido a CSS, y aplica transformaciones. Si quieres variables, anidamiento, mixins o minificación, añades el plugin correspondiente. Si no los necesitas, no los cargas. Esto tiene varias consecuencias prácticas:
- Puedes elegir exactamente qué transformaciones aplicar, sin cargar funciones que no usas.
- Puedes escribir CSS estándar y moderno y dejar que PostCSS lo adapte a navegadores antiguos, en lugar de aprender una sintaxis alternativa.
- Puedes combinarlo con un preprocesador: compilar Sass primero y aplicar después PostCSS para prefijos y minificación.
- Puedes crear tus propias transformaciones con unas pocas líneas de JavaScript.
El funcionamiento interno se resume en tres pasos. El analizador convierte el texto en un árbol de nodos, donde cada regla, declaración, comentario o regla @ es un objeto. Los plugins recorren y modifican ese árbol. El generador vuelve a convertirlo en texto, opcionalmente con un mapa de origen que relaciona el resultado con el archivo original.
Por ejemplo, esta pequeña hoja de estilo:
.boton {
color: white;
user-select: none;
}
Se representa internamente como un nodo raíz que contiene una regla con selector .boton, que a su vez contiene dos declaraciones con sus propiedades y valores. Los plugins trabajan sobre esa estructura, no sobre el texto, lo que hace las transformaciones mucho más fiables que una búsqueda y reemplazo.
Preparar el proyecto e instalar PostCSS
Para seguir el tutorial necesitas Node.js. Si vas a usar Stylelint 17, la versión mínima es Node.js 20.19, así que conviene trabajar con una versión LTS actual.
Crea un proyecto e instala PostCSS junto con su interfaz de línea de comandos como dependencias de desarrollo:
mkdir estilos-tienda && cd estilos-tienda
npm init -y
npm install -D postcss postcss-cli
A diferencia de algunos tutoriales antiguos, no es recomendable instalar postcss-cli de forma global. Una instalación local fija la versión en el package.json, garantiza que todo el equipo use la misma y permite ejecutarla con npx o desde scripts de npm.
Declara el proyecto como módulo ECMAScript para poder usar import y export en los archivos de configuración:
{
"name": "estilos-tienda",
"version": "1.0.0",
"type": "module",
"scripts": {}
}
La estructura de carpetas que usaremos es sencilla: el código fuente en src y el resultado procesado en dist.
estilos-tienda/
├── package.json
├── postcss.config.js
├── .browserslistrc
├── stylelint.config.js
├── src/
│ ├── principal.css
│ ├── base/
│ │ └── tipografia.css
│ └── componentes/
│ ├── boton.css
│ └── tarjeta.css
└── dist/
└── principal.css
Comprueba que la CLI funciona procesando un archivo sin plugins:
npx postcss src/principal.css -o dist/principal.css
El resultado será idéntico a la entrada, porque todavía no hemos cargado ningún plugin. PostCSS solo ha leído el archivo y lo ha vuelto a escribir.
Definir los navegadores objetivo con Browserslist
Muchos plugins de PostCSS necesitan saber qué navegadores quieres soportar para decidir qué transformaciones aplicar. En lugar de configurar esa lista en cada plugin, el ecosistema usa una fuente común llamada Browserslist.
Crea un archivo .browserslistrc en la raíz del proyecto:
# .browserslistrc
defaults
not dead
La consulta defaults incluye una selección razonable de navegadores con uso significativo y todavía mantenidos. Puedes ajustarla según tu público. Por ejemplo, una aplicación interna de empresa que solo se usa en navegadores recientes podría declarar:
# .browserslistrc para una aplicación interna
last 2 Chrome versions
last 2 Edge versions
last 2 Firefox versions
last 2 Safari versions
Para ver qué navegadores concretos incluye tu consulta, ejecuta:
npx browserslist
and_chr 141
chrome 141
chrome 140
edge 141
firefox 144
ios_saf 26.0
safari 26.0
...
La lista exacta dependerá de la fecha en que lo ejecutes, porque Browserslist usa datos de uso de navegadores que se actualizan con frecuencia. Para mantenerlos al día, ejecuta periódicamente:
npx update-browserslist-db@latest
Si no lo haces, verás una advertencia indicando que los datos de navegadores están desactualizados, y los plugins tomarán decisiones con información antigua.
Prefijos de proveedor con Autoprefixer
Autoprefixer es probablemente el plugin de PostCSS más utilizado del mundo. Su función es añadir prefijos de proveedor automáticos como -webkit- o -moz- solo a las propiedades que los necesitan para los navegadores de tu lista, usando los datos de compatibilidad de Can I Use.
Instálalo:
npm install -D autoprefixer
Y crea el archivo de configuración de PostCSS con el plugin:
// postcss.config.js
import autoprefixer from "autoprefixer";
export default {
plugins: [autoprefixer()],
};
Con una entrada como esta:
.campo-busqueda::placeholder {
color: #8a8a8a;
}
.galeria {
user-select: none;
backdrop-filter: blur(6px);
}
El resultado dependerá de tus navegadores objetivo. Si incluyes versiones antiguas de Safari, obtendrás algo similar a:
.campo-busqueda::placeholder {
color: #8a8a8a;
}
.galeria {
-webkit-user-select: none;
user-select: none;
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
}
Lo importante es que nunca escribes prefijos a mano. Escribes la propiedad estándar, y cuando un navegador deja de necesitar el prefijo, basta con actualizar Browserslist para que Autoprefixer lo elimine del resultado. También funciona en sentido inverso: si tu código fuente contiene prefijos obsoletos escritos manualmente, Autoprefixer los elimina.
Para revisar qué prefijos se aplicarían con tu configuración, sin procesar ningún archivo, puedes ejecutar:
npx autoprefixer --info
Usar CSS moderno con PostCSS Preset Env
Mientras Autoprefixer se ocupa de los prefijos, PostCSS Preset Env va un paso más allá: permite usar CSS moderno hoy convirtiendo características recientes en código equivalente que entienden navegadores más antiguos. Hace con CSS lo mismo que hace Babel con JavaScript.
npm install -D postcss-preset-env
Preset Env incluye Autoprefixer internamente, así que no necesitas cargar ambos. Si lo haces, los prefijos se procesarían dos veces sin ningún beneficio.
// postcss.config.js
import postcssPresetEnv from "postcss-preset-env";
export default {
plugins: [
postcssPresetEnv({
stage: 2,
features: {
"nesting-rules": true,
"custom-media-queries": true,
},
}),
],
};
La opción stage controla qué tan experimentales pueden ser las características que se transforman. Las etapas siguen la clasificación del proyecto cssdb, que va de 0, para ideas muy tempranas, a 4, para estándares consolidados. El valor por defecto es 2, un buen equilibrio. Con features puedes activar o desactivar características concretas independientemente de su etapa.
Veamos un ejemplo con anidamiento, consultas de medios personalizadas y la función color-mix:
@custom-media --tableta (width >= 768px);
.tarjeta-producto {
padding: 1rem;
background: color-mix(in srgb, #2a6df4 15%, white);
& h3 {
margin-block: 0 0.5rem;
}
@media (--tableta) {
padding: 2rem;
}
}
Para navegadores que no soportan estas características, Preset Env genera código aplanado, expande la consulta personalizada y calcula un color de respaldo. Para navegadores modernos de tu lista, deja intacto lo que ya entienden.
Un apunte importante sobre el anidamiento: hoy es una característica nativa de CSS soportada por todos los navegadores principales. Si tu lista de navegadores es moderna, Preset Env no lo transformará, y el CSS anidado llegará tal cual al navegador. Si necesitas compatibilidad con navegadores anteriores, el plugin se encarga de aplanarlo.
Organizar archivos con postcss-import
El @import nativo de CSS funciona en los navegadores, pero cada importación es una petición de red adicional que el navegador descubre secuencialmente, lo que retrasa la carga. El plugin postcss-import resuelve las importaciones durante la compilación e inserta el contenido de cada archivo en uno solo.
npm install -D postcss-import
Con él puedes organizar el código en archivos pequeños y temáticos:
/* src/principal.css */
@import "./base/tipografia.css";
@import "./componentes/boton.css";
@import "./componentes/tarjeta.css";
Este plugin debe ir siempre el primero en la lista. El motivo es lógico: el resto de plugins deben ver el CSS completo, con todos los archivos ya combinados. Si Preset Env se ejecutara antes, solo procesaría el archivo principal y dejaría sin transformar el contenido de los importados.
// postcss.config.js
import postcssImport from "postcss-import";
import postcssPresetEnv from "postcss-preset-env";
export default {
plugins: [postcssImport(), postcssPresetEnv({ stage: 2 })],
};
El plugin también resuelve importaciones desde node_modules, lo que permite incluir hojas de estilo de paquetes instalados con npm escribiendo solo el nombre del paquete.
Anidamiento y mixins: postcss-nested y postcss-mixins
Si vienes de Sass, quizá eches de menos dos funcionalidades: el anidamiento con su semántica particular y los mixins. Existen plugins específicos para ambas.
El plugin postcss-nested implementa el anidamiento con el comportamiento de Sass, que no es idéntico al del estándar. La diferencia más visible es la concatenación de selectores con &. En Sass, &__titulo dentro de .tarjeta produce .tarjeta__titulo, algo muy útil con la metodología BEM. El anidamiento nativo de CSS no permite esa concatenación.
.tarjeta {
border-radius: 8px;
&__titulo {
font-size: 1.25rem;
}
&--destacada {
border: 2px solid gold;
}
}
Con postcss-nested el resultado es:
.tarjeta {
border-radius: 8px;
}
.tarjeta__titulo {
font-size: 1.25rem;
}
.tarjeta--destacada {
border: 2px solid gold;
}
Si tu proyecto no usa concatenación de selectores, es preferible escribir anidamiento estándar y dejar que Preset Env lo gestione, porque tu código seguirá siendo CSS válido sin depender de ningún plugin. Usa postcss-nested solo si necesitas la semántica de Sass, y evita combinar ambos enfoques en el mismo proyecto.
El plugin postcss-mixins permite definir bloques de declaraciones reutilizables:
@define-mixin lista-limpia {
margin: 0;
padding: 0;
list-style: none;
}
@define-mixin truncar $lineas {
display: -webkit-box;
-webkit-line-clamp: $lineas;
-webkit-box-orient: vertical;
overflow: hidden;
}
.menu-principal ul {
@mixin lista-limpia;
}
.resumen-producto {
@mixin truncar 3;
}
Los mixins se expanden en tiempo de compilación, por lo que el navegador recibe declaraciones normales. Ten en cuenta que el orden importa: postcss-mixins debe ejecutarse antes que los plugins de anidamiento para que las reglas anidadas dentro de un mixin se procesen correctamente.
Revisar la calidad del código con Stylelint
Stylelint es un analizador estático para CSS que detecta errores, como colores hexadecimales inválidos o propiedades desconocidas, y hace cumplir convenciones de estilo del equipo. Está construido sobre PostCSS, por lo que entiende tanto CSS estándar como sintaxis extendidas.
npm install -D stylelint stylelint-config-standard
La versión 17 introdujo cambios importantes: ahora es exclusivamente un módulo ECMAScript, eliminó la antigua API de CommonJS y exige Node.js 20.19 o superior. Además, las rutas locales en extends y plugins deben indicarse completas. La configuración recomendada es un archivo propio en lugar de una clave dentro del package.json:
// stylelint.config.js
export default {
extends: ["stylelint-config-standard"],
rules: {
"color-no-invalid-hex": true,
"selector-class-pattern": [
"^[a-z][a-z0-9-]*(__[a-z0-9-]+)?(--[a-z0-9-]+)?$",
{ message: "Usa nombres de clase en minúsculas con formato BEM" },
],
},
};
Por defecto Stylelint no activa ninguna regla, por eso es habitual partir de una configuración compartida como stylelint-config-standard y ajustar solo lo necesario.
Aunque Stylelint puede integrarse como un plugin más dentro de la cadena de PostCSS, hoy lo habitual es ejecutarlo como una herramienta independiente, desde su propia CLI, el editor o el sistema de integración continua. Así los errores de estilo no se mezclan con la compilación:
npx stylelint "src/**/*.css"
src/componentes/boton.css
4:10 ✖ Unexpected invalid hex color "#3a6gff" color-no-invalid-hex
9:1 ✖ Expected class selector ".BotonGrande" to match pattern selector-class-pattern
✖ 2 problems (2 errors, 0 warnings)
Muchas reglas pueden corregirse automáticamente con la opción --fix.
Minificar CSS para producción con cssnano
La última etapa de la cadena suele ser la minificación. cssnano es un optimizador construido sobre PostCSS que reduce el tamaño del archivo eliminando espacios y comentarios, pero también aplicando optimizaciones más profundas: fusionar reglas duplicadas, acortar colores, simplificar valores y eliminar declaraciones redundantes.
npm install -D cssnano
Para minificar CSS para producción sin afectar al desarrollo, lo ideal es aplicar cssnano solo cuando se construye la versión final. La configuración de PostCSS puede exportar una función que recibe un contexto con el entorno:
// postcss.config.js
import postcssImport from "postcss-import";
import postcssMixins from "postcss-mixins";
import postcssPresetEnv from "postcss-preset-env";
import cssnano from "cssnano";
export default (ctx) => {
const esProduccion = ctx.env === "production";
return {
map: !esProduccion,
plugins: [
postcssImport(),
postcssMixins(),
postcssPresetEnv({ stage: 2 }),
esProduccion && cssnano({ preset: "default" }),
].filter(Boolean),
};
};
Con una entrada como esta:
/* Botón principal de compra */
.boton-comprar {
background-color: #ffffff;
margin: 0px 0px 0px 0px;
color: #ff0000;
}
.boton-comprar {
font-weight: 700;
}
cssnano genera:
.boton-comprar {
background-color: #fff;
color: red;
font-weight: 700;
margin: 0;
}
El comentario desaparece, el color blanco se acorta, el rojo se sustituye por su nombre porque ocupa menos, los márgenes se simplifican y las dos reglas con el mismo selector se fusionan. El preset default aplica solo optimizaciones seguras; existe también un preset advanced más agresivo, que conviene probar con cuidado porque algunas de sus transformaciones pueden alterar el resultado en casos límite.
Fíjate también en la opción map: en desarrollo genera mapas de origen para que las herramientas del navegador muestren la línea original de cada regla, y en producción los omite.
Trabajar con la línea de comandos y scripts de npm
Con la configuración lista, la CLI solo necesita saber qué archivos procesar y dónde escribir el resultado. Los plugins se leen automáticamente de postcss.config.js.
Los comandos más habituales son estos:
# Procesar un archivo a un archivo de salida concreto
npx postcss src/principal.css -o dist/principal.css
# Procesar varios archivos hacia una carpeta
npx postcss "src/paginas/*.css" --dir dist/paginas
# Vigilar cambios y recompilar automáticamente
npx postcss src/principal.css -o dist/principal.css --watch
# Indicar el entorno que recibe la configuración
npx postcss src/principal.css -o dist/principal.css --env production
En lugar de recordar estos comandos, agrúpalos en scripts del package.json:
{
"type": "module",
"scripts": {
"css:dev": "postcss src/principal.css -o dist/principal.css --watch",
"css:build": "postcss src/principal.css -o dist/principal.css --env production",
"css:lint": "stylelint \"src/**/*.css\""
}
}
Ahora basta con ejecutar npm run css:dev mientras trabajas y npm run css:build antes de publicar:
npm run css:build
> [email protected] css:build
> postcss src/principal.css -o dist/principal.css --env production
Hace algunos años era común integrar PostCSS mediante ejecutores de tareas como Grunt o Gulp. Siguen existiendo, pero en proyectos nuevos han sido desplazados por los scripts de npm y por los empaquetadores modernos, que incluyen PostCSS de serie.
Integración con Vite y otros empaquetadores
Si tu proyecto usa Vite, no necesitas la CLI de PostCSS. Vite procesa automáticamente cualquier archivo CSS importado con PostCSS si encuentra un archivo de configuración en la raíz del proyecto. Basta con tener el mismo postcss.config.js que hemos construido:
// src/main.js
import "./principal.css";
Vite detecta la configuración, aplica los plugins durante el desarrollo con recarga en caliente y genera el CSS final al construir. También puedes definir los plugins directamente en vite.config.js si prefieres centralizar la configuración:
// vite.config.js
import { defineConfig } from "vite";
import postcssPresetEnv from "postcss-preset-env";
export default defineConfig({
css: {
postcss: {
plugins: [postcssPresetEnv({ stage: 2 })],
},
},
});
Ten en cuenta que Vite ya minifica el CSS en sus compilaciones de producción, así que añadir cssnano en un proyecto con Vite suele ser redundante.
En webpack, la integración se hace mediante postcss-loader, que se coloca en la cadena de loaders de CSS después de css-loader. Frameworks como Next.js, Angular o Astro también leen el archivo de configuración de PostCSS del proyecto, por lo que todo lo aprendido aquí se aplica directamente.
Escribir tu propio plugin de PostCSS
Una de las mayores ventajas de PostCSS es lo sencillo que resulta escribir tu propio plugin cuando ningún paquete existente cubre una necesidad. Un plugin es una función que devuelve un objeto con un nombre y uno o más visitantes, funciones que se ejecutan al encontrar determinados tipos de nodo.
Como ejemplo, crearemos un plugin que convierta valores en píxeles a unidades rem, algo útil para que la tipografía respete el tamaño de fuente configurado por el usuario en su navegador:
// plugins/px-a-rem.js
const PX = /(-?\d*\.?\d+)px\b/g;
const pxARem = ({
base = 16,
propiedades = ["font-size", "line-height", "letter-spacing"],
} = {}) => ({
postcssPlugin: "px-a-rem",
Declaration(declaracion) {
if (!propiedades.includes(declaracion.prop)) return;
if (!declaracion.value.includes("px")) return;
declaracion.value = declaracion.value.replace(PX, (_, numero) => {
const rem = Number(numero) / base;
return `${Number(rem.toFixed(4))}rem`;
});
},
});
pxARem.postcss = true;
export default pxARem;
La propiedad postcss = true indica a PostCSS que la función es un plugin compatible con la API de la versión 8. El visitante Declaration se ejecuta para cada declaración del árbol; existen también visitantes para Rule, AtRule, Comment, Once y OnceExit, entre otros.
Para usarlo, añádelo a la configuración como cualquier otro plugin:
// postcss.config.js (fragmento)
import pxARem from "./plugins/px-a-rem.js";
export default {
plugins: [pxARem({ base: 16 })],
};
Con esta entrada:
.titulo-seccion {
font-size: 28px;
letter-spacing: -0.5px;
margin: 24px;
}
El resultado es:
.titulo-seccion {
font-size: 1.75rem;
letter-spacing: -0.0313rem;
margin: 24px;
}
El margen no cambia porque no está en la lista de propiedades configurada. También puedes probar el plugin directamente con la API de JavaScript de PostCSS, sin pasar por la CLI, lo cual es ideal para escribir pruebas automatizadas:
// pruebas/px-a-rem.test.js
import postcss from "postcss";
import pxARem from "../plugins/px-a-rem.js";
const css = ".a { font-size: 20px; }";
const resultado = await postcss([pxARem()]).process(css, { from: undefined });
console.log(resultado.css);
.a { font-size: 1.25rem; }
Errores comunes y cómo resolverlos
Durante la configuración es frecuente encontrarse con algunos mensajes recurrentes.
Error: PostCSS plugin autoprefixer requires PostCSS 8.
Algún plugin espera la API de PostCSS 8, pero el proyecto o alguna dependencia resuelve una versión anterior. Ejecuta npm ls postcss para localizar versiones duplicadas y actualiza los paquetes que arrastran la versión antigua.
Browserslist: browsers data (caniuse-lite) is X months old.
Los datos de compatibilidad están desactualizados. Ejecuta npx update-browserslist-db@latest para refrescarlos.
CssSyntaxError: postcss-import: src/principal.css:3:1: Failed to find './componentes/boton.css'
La ruta del archivo importado es incorrecta o el plugin no está configurado. Recuerda que las rutas relativas se resuelven desde el archivo que contiene el @import.
Error [ERR_REQUIRE_ESM]: require() of ES Module stylelint.config.js not supported.
Estás mezclando CommonJS y módulos ECMAScript. Con Stylelint 17 y "type": "module" en el package.json, todos los archivos de configuración deben usar export default. Si necesitas mantener un archivo en CommonJS, usa la extensión .cjs.
Otros problemas sin mensaje explícito:
- El anidamiento no se aplana: probablemente tus navegadores objetivo ya soportan anidamiento nativo, y Preset Env lo deja intacto a propósito.
- Los prefijos aparecen duplicados o se procesan dos veces: estás cargando Autoprefixer y Preset Env a la vez.
- Los archivos importados no se transforman:
postcss-importno es el primer plugin de la lista.
Alternativas a PostCSS y cuándo elegir cada una
PostCSS no es la única opción para procesar CSS, y conviene conocer el panorama actual.
Sass sigue siendo muy popular, especialmente en proyectos con mucha lógica de estilos, como sistemas de diseño con funciones, bucles y mapas. Si tu equipo ya domina Sass, puedes mantenerlo y añadir PostCSS solo para prefijos y minificación.
Lightning CSS es un procesador escrito en Rust que combina en una sola herramienta el análisis, la transformación de sintaxis moderna, los prefijos y la minificación, con un rendimiento muy superior al de una cadena de plugins en JavaScript. Su contrapartida es que no ofrece un ecosistema de plugins comparable. Vite permite usarlo como alternativa a PostCSS, y Tailwind CSS en su versión 4 lo usa internamente, de modo que ya no requiere configurar Autoprefixer por separado.
El propio CSS moderno también reduce la necesidad de herramientas: variables nativas, anidamiento, color-mix, consultas de contenedor y capas de cascada están disponibles en todos los navegadores principales. Para proyectos que solo apuntan a navegadores recientes, a veces basta con escribir CSS estándar y minificarlo.
PostCSS sigue siendo la mejor opción cuando necesitas flexibilidad: combinar transformaciones específicas, integrar herramientas como Tailwind o Stylelint, mantener compatibilidad con navegadores más antiguos o crear transformaciones propias para tu organización.
Buenas prácticas para proyectos en producción
Para sacar el máximo partido de PostCSS a largo plazo, conviene seguir algunas recomendaciones.
Mantén la lista de plugins corta y justificada. Cada plugin añade tiempo de compilación y complejidad. Revisa periódicamente si alguno ha quedado obsoleto porque los navegadores ya soportan la característica de forma nativa.
Respeta el orden de la cadena: primero importaciones, después mixins y transformaciones de sintaxis, luego prefijos y, al final, minificación.
Prefiere sintaxis estándar frente a sintaxis propietaria de plugins. El CSS estándar seguirá funcionando aunque algún día elimines PostCSS; la sintaxis de un plugin te ata a él.
Comparte la configuración de Browserslist entre todas las herramientas del proyecto, incluido Babel si lo usas, para que JavaScript y CSS apunten a los mismos navegadores.
Ejecuta Stylelint en la integración continua y en el editor, no solo en local, para detectar errores antes de que lleguen a la rama principal.
Versiona package-lock.json y fija las versiones de los plugins. Un cambio de versión menor en un plugin puede alterar el CSS generado, y conviene revisarlo de forma consciente.
Conclusiones
PostCSS es una plataforma de transformación de CSS basada en plugins, no un lenguaje. Lee tu CSS, lo convierte en un árbol, deja que cada plugin lo modifique y genera el resultado. Esa arquitectura simple explica su enorme adopción: forma parte de la cadena de herramientas de la mayoría de frameworks y empaquetadores modernos.
A lo largo del tutorial hemos montado una cadena completa con las versiones actuales: postcss-import para organizar archivos, postcss-mixins y postcss-nested para reutilización y anidamiento al estilo Sass, PostCSS Preset Env para escribir CSS moderno con compatibilidad hacia atrás, Autoprefixer para los prefijos, cssnano para la minificación y Stylelint 17 para mantener la calidad del código. También hemos visto cómo ejecutarla con la CLI y scripts de npm, cómo integrarla en Vite y cómo crear un plugin propio con la API de PostCSS 8.
El ecosistema sigue evolucionando. Características como el anidamiento ya son nativas, herramientas como Lightning CSS ofrecen alternativas más rápidas para casos estándar, y Stylelint ha dado el salto definitivo a los módulos ECMAScript. Entender cómo funciona PostCSS por dentro te permitirá adaptar tu configuración a esos cambios con criterio, eligiendo en cada proyecto solo las transformaciones que realmente aportan valor.
