Formatear, minificar y convertir entre CSS y SCSS.
Cómo resuelve la cascada la terna (A,B,C), qué transformaciones son seguras al comprimir y qué construcciones de Sass no tienen equivalente nativo.
El nivel 5 de la especificación CSS Cascade calcula la especificidad con tres contadores independientes: A cuenta selectores de ID, B cuenta clases, selectores de atributo y pseudoclases, y C cuenta tipos de elemento y pseudoelementos. `#nav .item > a:hover` vale (1,2,1): un ID, una clase más una pseudoclase, y un tipo. La comparación es lexicográfica, así que (1,0,0) gana a (0,10,0) por muchas clases que se acumulen. `:where()` aporta siempre (0,0,0), incluso cuando envuelve un selector de ID, mientras que `:is()` adopta la especificidad de su argumento más alto. El atributo `style` en línea no participa en esta cuenta: pertenece a un nivel superior de la cascada.
Un minificador seguro elimina espacios, saltos de línea y comentarios, borra el punto y coma que precede a `}`, recorta el cero inicial (`0.5em` pasa a `.5em`), quita la unidad de las longitudes nulas (`margin: 0px` pasa a `margin: 0`) y colapsa colores hexadecimales de seis dígitos a tres cuando los pares se repiten (`#ffffff` pasa a `#fff`). Lo que no puede hacer sin riesgo es reordenar declaraciones que colisionan, fusionar propiedades longhand en un shorthand cuando alguna usa `var()` (el valor se desconoce hasta el tiempo de ejecución) ni borrar los comentarios marcados `/*! ... */`, reservados para cabeceras de licencia. Sobre una respuesta ya comprimida con gzip o Brotli, el ahorro extra suele quedar entre el 3 % y el 8 %.
El anidamiento nativo, las propiedades personalizadas y las capas de cascada cubren hoy casi todo aquello para lo que se usaba Sass, pero las diferencias importan. `$color: red` es una sustitución en tiempo de compilación que desaparece del archivo final, mientras que `--color: red` vive en el CSSOM, se hereda por el árbol, se puede leer con `getComputedStyle()` y reasignar desde JavaScript. Las funciones, `@mixin`, `@extend` y los bucles `@each` no tienen equivalente nativo. Una propiedad personalizada tampoco sirve como condición de una media query: `@media (width > var(--bp))` no es válido. Declarar `@layer base, components;` fija la prioridad por capa, de modo que una regla de componente con poca especificidad deja de depender del orden de los imports.
`!important` no es un comodín absoluto. Cuando dos declaraciones del mismo origen llevan `!important`, gana la de mayor especificidad y, en caso de empate, la última en aparecer. Además, una animación en curso pisa cualquier declaración importante mientras corren sus keyframes, y las declaraciones importantes de las hojas de usuario y del agente de usuario tienen prioridad sobre las importantes del autor.
Se resuelven a su valor literal y desaparecen del resultado. Si necesitás cambiar de tema en tiempo de ejecución, hay que reescribirlas como propiedades personalizadas: `--brand: #0af` en `:root` y `color: var(--brand, #08c)` en el punto de uso, donde el segundo argumento es el valor de reserva que se aplica si la variable no está definida.
Menos de lo que parece. La minificación reduce el archivo en bruto entre un 15 % y un 25 %, pero gzip y Brotli ya comprimen muy eficientemente los espacios repetidos, así que el ahorro adicional sobre la respuesta comprimida ronda el 3-8 %. La mejora real en el renderizado viene de eliminar reglas sin uso y de separar el CSS crítico del diferido.