Auditoría de una hoja de estilos con Project Wallace
Una auditoría CSS con Project Wallace convierte colores únicos, tamaños de fuente, especificidad, duplicados y tamaño de archivo en correcciones.
Una auditoría de CSS con Project Wallace consiste en pegar una hoja de estilos en el analizador en línea y leer cinco números: colores únicos, tamaños de fuente únicos, especificidad máxima de selector (con el recuento de ids y de !important a su lado), la diferencia entre declaraciones totales y únicas, y el tamaño de archivo sin comprimir frente al tamaño con gzip. Cada número apunta a un cambio distinto.
Si tu hoja de estilos tiene tres años, probablemente ya sospechas que se ha desviado. Lo que te falta es un número que poner en un ticket. «El CSS se siente desordenado» no se prioriza; «enviamos seis grises donde el diseño define dos» sí.
Este artículo pasa una pequeña hoja de estilos de ejemplo por el analizador, lee la salida métrica por métrica y empareja cada hallazgo con el cambio concreto que debería desencadenar. Cubre el diagnóstico. El artículo complementario, How to Organize CSS in Modern Web Projects, cubre el tratamiento.
Puntos clave
- Los navegadores descartan el CSS que no pueden parsear o que no reconocen y siguen renderizando, así que una hoja de estilos acumula errores sin que nunca falle una compilación.
- Cuando pegas o subes CSS, Project Wallace ejecuta el análisis en un WebWorker en tu propio dispositivo, por lo que la hoja de estilos nunca sale del navegador.
- La diferencia entre los colores únicos que se envían y la paleta que define el diseño es la forma medible de la desviación de diseño, y la solución es consolidar valores en tokens, no eliminar reglas.
- Un pico de especificidad a mitad de la hoja de estilos cuesta más que un máximo elevado al final, porque cada override posterior tiene que escalar para igualarlo.
- Las reglas vacías son la única corrección de auditoría que nunca necesita una comprobación de regresión visual; las declaraciones duplicadas requieren criterio antes de eliminarlas.
¿Por qué una auditoría de CSS encuentra lo que la compilación no puede?
Un navegador que se encuentra con una declaración CSS que no puede parsear o que no reconoce descarta esa declaración y sigue renderizando la página, y por eso una hoja de estilos puede acumular errores durante años sin que ninguna compilación falle jamás. Esa recuperación es comportamiento especificado. Según las reglas de manejo de errores del CSS Syntax Module Level 3, la declaración a medio construir se descarta, el parser avanza más allá del siguiente punto y coma, y el parseo normal continúa desde ahí.
La consecuencia es que el daño en CSS nunca parece un fallo. Parece desviación: un cuarto gris que está a dos puntos del tercero, un encabezado de 17px entre los pasos de 16px y 18px, un selector de id añadido bajo presión de plazos y luego un !important añadido para superarlo. Nada de esto rompe nada. Todo ello hace que el siguiente cambio sea más difícil.
¿Cómo se ejecuta el analizador de Project Wallace?
El analizador de CSS de Project Wallace acepta entrada de tres formas: una URL de sitio web, un archivo subido o CSS pegado directamente. Cuando pegas o subes CSS, el trabajo ocurre localmente: un WebWorker en tu propio dispositivo hace el análisis, y nada de lo que pegas se envía a ningún sitio. Ese diseño se remonta a la reescritura del analizador de 2021. El modo URL necesariamente descarga el sitio objetivo por red antes del análisis.
La página de entrada tiene un conmutador «Prettify CSS?», con una nota al lado que advierte de que la opción altera ligeramente los números. Elige un estado y mantenlo fijo en todas las ejecuciones que pretendas comparar.
Aquí está la hoja de ejemplo. Tres colaboradores, dos años, un componente de encabezado y uno de tarjeta:
/* header.css — three contributors, two years */
#site-header {
background: #f5f5f5;
color: #333333;
font-size: 16px;
}
#site-header .nav-link {
color: #343434;
font-size: 15px;
padding: 8px 12px;
}
.nav-link:hover {
color: #222222 !important;
}
.card {
background: #f4f4f4;
color: #333333;
font-size: 1rem;
padding: 16px;
}
.card .card-title {
font-size: 18px;
color: #333333;
}
.card--featured .card-title {
font-size: 17px;
font-weight: 700 !important;
}
.legacy-banner {
}
.footer {
background: #f5f5f5;
color: #444444;
font-size: 14px;
}
Lo que devuelve es una página de resultados agrupada en las mismas categorías que la documentación de métricas: Stylesheet, Atrules, Rules, Selectors, Declarations, Properties y Values. Hay bastante más de cien métricas. Las cinco de abajo son las que se convierten en un commit.
¿Qué te dicen los colores y tamaños de fuente únicos?
La diferencia entre colores totales y colores únicos te dice con qué frecuencia se reutiliza cada color, y la diferencia entre colores únicos y la paleta que define tu sistema de diseño te dice cuánto se ha desviado el código respecto al diseño. El analizador cuenta ambos y te da la lista completa de colores únicos que encontró; los tamaños de fuente reciben el mismo tratamiento.
Leída a mano, la hoja de ejemplo contiene seis cadenas hexadecimales distintas: #f5f5f5 y #f4f4f4 para superficies, y #333333, #343434, #222222, #444444 para texto. Un sistema de diseño para este componente casi con certeza pretendía una superficie y dos colores de texto. La escala tipográfica es peor: 16px, 15px, 1rem, 18px, 17px, 14px son seis valores tal como están escritos, y 16px y 1rem normalmente resuelven al mismo tamaño en píxeles de todos modos.
La solución es consolidación, no eliminación. Consolidar grises casi idénticos no significa eliminar reglas; significa reemplazar cada literal por el token más cercano y dejar que la regla siga cumpliendo su función:
:root {
--color-surface: #f5f5f5;
--color-text: #333333;
--color-text-muted: #444444;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
}
.card {
background: var(--color-surface);
color: var(--color-text);
font-size: var(--font-size-base);
padding: 16px;
}
Tres tokens de color reemplazan seis literales; tres tokens de tamaño reemplazan seis. La herramienta de Design Tokens independiente de Project Wallace extrae colores y tamaños de fuente candidatos del CSS existente, lo cual es un punto de partida más rápido que leer la lista a mano en una hoja de estilos real.
Especificidad: los picos importan más que el máximo
Un selector de alta especificidad cerca del final de una hoja de estilos es un problema local, pero uno en el medio obliga a cada regla posterior que necesite sobrescribirlo a escalar al mismo nivel, y esa escalada es la forma en que los selectores de id y los flags !important se multiplican. El gráfico de especificidad de Harry Roberts plantea el mismo argumento visualmente: la tendencia debería subir suavemente hacia el final, y cualquier pico es un coste que paga todo lo que viene después.
El analizador informa la especificidad como un valor de tres partes (id, clase, tipo) mediante Maximum selector specificity, Total selectors having maximum specificity y Top specificity selectors, junto con Total id selectors, Total !important declarations y Ratio of !important declarations.
La hoja de ejemplo muestra el mecanismo en miniatura. #site-header .nav-link se sitúa en (1,1,0). La posterior .nav-link:hover en (0,2,0) no puede superarla, así que un colaborador recurrió a !important. Un selector de id produjo un flag !important, y el segundo flag en .card--featured .card-title supera una regla que nunca estableció font-weight en absoluto.
El recuento de selectores de id y el recuento de !important son los dos números de especificidad que un equipo puede reducir un commit a la vez y volver a medir después de cada cambio. En la hoja de ejemplo, cambiar el marcado de id="site-header" a class="site-header" aplana ambas reglas del encabezado a (0,1,0) y (0,2,0), y ambos flags !important se vuelven innecesarios.
Declaraciones duplicadas y reglas vacías
Una regla vacía aporta bytes y una coincidencia de selector, pero no cambia nada que el usuario vea, así que eliminarla es la única corrección de auditoría que nunca necesita una comprobación de regresión visual. Las declaraciones duplicadas son distintas: la misma intención escrita dos veces es un síntoma, pero eliminar la copia equivocada cambia la cascada.
El analizador cuenta Total empty rules directamente; .legacy-banner {} es la única instancia de la hoja de ejemplo, y se va. No hay una métrica independiente de declaraciones duplicadas. Lee Total declarations frente a Total unique declarations y trata la diferencia como el recuento de duplicados, teniendo en cuenta que la documentación aún deja abierto si los espacios en blanco o el formato hacen que dos declaraciones sean distintas.
color: #333333 aparece en tres reglas de la hoja de ejemplo. La acción correcta no es eliminar dos copias, sino enrutar las tres a través de var(--color-text), lo que hace que la repetición sea visible como una decisión compartida en lugar de una coincidencia.
¿Por qué el tamaño con gzip oculta una hoja de estilos inflada?
Gzip comprime la repetición de forma eficiente, así que una hoja de estilos llena de declaraciones duplicadas puede mostrar un tamaño comprimido halagador mientras su tamaño sin comprimir, los bytes que el navegador realmente parsea, sigue creciendo. El analizador informa Uncompressed filesize, Gzip filesize y Gzip filesize compression ratio en conjunto.
Un ratio de compresión en aumento es la señal: significa que la hoja de estilos se está volviendo más repetitiva, no más pequeña. Lo que mueve el tamaño sin comprimir es el número de reglas y declaraciones, y por eso el trabajo de consolidación anterior lo reduce como efecto secundario. El tamaño de archivo es un diagnóstico para leer después de las otras correcciones, no un objetivo que optimizar por sí mismo.
Seguimiento de una hoja de estilos a lo largo de las releases
Para hacer seguimiento de una hoja de estilos a lo largo de las releases, guarda el CSS en bruto de cada release junto con sus resultados del analizador y vuelve a ejecutar cada análisis con el mismo estado de Prettify. El visor CSS Diff formatea dos hojas de estilos pegadas y las compara línea por línea en el navegador, lo que muestra dónde se movió el recuento de colores únicos o de selectores de id.
Conclusión
Una auditoría de hoja de estilos justifica su tiempo cuando cada número se corresponde con un cambio: colores y tamaños de fuente únicos a tokens, selectores de id y flags !important a una especificidad más plana, reglas vacías a eliminación, duplicados a declaraciones compartidas, y tamaño de archivo a una comprobación de que el resto funcionó. Pega tu hoja de estilos de producción más grande en el analizador, anota esos cinco números y abre un pull request por número.
Preguntas frecuentes
¿Puedo ejecutar el analizador de Project Wallace desde la línea de comandos o en CI?
Sí. El paquete npm wallace-cli ejecuta el mismo analizador en una terminal: instálalo con npm install wallace-cli, luego ejecuta wallace path/to/styles.css o pásale CSS por stdin, y añade el flag --json para obtener salida legible por máquina en scripts de CI. La versión 4.x de la CLI requiere Node 20.12 o posterior. Para uso programático, importa la función analyze de @projectwallace/css-analyzer, un paquete solo ESM que funciona tanto en Node como en navegadores.
¿Debo analizar mis archivos fuente de Sass o Tailwind o el CSS compilado?
Analiza el CSS compilado que reciben tus usuarios, no el fuente de Sass, Less o Tailwind. Las variables, los mixins y @extend se expanden en tiempo de compilación, así que los archivos fuente informan mal los colores únicos, los recuentos de selectores y el tamaño de archivo. El propio plugin de Stylelint de Project Wallace dice lo mismo sobre dónde apuntarlo: dirígelo al bundle que envías, porque los recuentos de valores únicos y los ratios construidos sobre ellos describen el archivo entregado y no el fuente. El modo URL ya descarga las hojas de estilos compiladas que sirve un sitio.
¿Cuál es la diferencia entre el CSS Analyzer de Project Wallace y su herramienta CSS Code Quality?
El CSS Analyzer informa métricas en bruto; la herramienta CSS Code Quality toma esa salida, ejecuta sus propias comprobaciones sobre ella y reduce el resultado a tres puntuaciones sobre 100, de Performance, Maintainability y Complexity. Usa el analizador cuando necesites rastrear un número hasta una regla concreta, y Code Quality cuando quieras un resumen con criterio para compartir con un equipo. Ambos aceptan una URL, archivos subidos o CSS pegado.
¿Cómo evito que los colores únicos o la especificidad retrocedan después de una auditoría?
Añade @projectwallace/stylelint-plugin a tu configuración de Stylelint. Incluye más de 60 reglas construidas sobre el mismo motor de análisis, entre ellas projectwallace/max-unique-colors, y su preset holistic juzga el archivo en su conjunto (totales, promedios, ratios, unicidad) en lugar de comprobar un nodo a la vez. Un preset recommended te pone en marcha con una única línea extends. Ejecútalo contra el bundle de CSS compilado en CI para que un pull request que añada un séptimo gris falle antes del merge.