Utility-first, Tailwind y estrategias de styling | Nicolás Garzón
Inicio Wiki CSS Utility-first, Tailwind y estrategias de styling Volver a CSSCSS
Utility-first, Tailwind y estrategias de styling Compara utility-first, Tailwind, CSS Modules, CSS-in-JS y estilos globales según composición, alcance, runtime, tooling y mantenimiento.
Última actualización Actualizada 24 de jul de 2026
Una estrategia de styling decide dónde se expresan las reglas, cómo se reutilizan y cómo se controla la cascada. No cambia los fundamentos de CSS.
Nota anteriorSistemas de diseño y Atomic Design Nota siguiente Rendimiento, containment y content-visibility HTML
Copiar < button class = " inline-flex items-center gap-2 rounded-lg px-4 py-3" >
Guardar
</ button> CSS
Copiar .button {
display : inline-flex;
align-items : center;
gap : 0.5rem;
padding : 0.75rem 1rem;
border-radius : 0.75rem;
} HTML
Copiar < button class = " button" > Guardar</ button> La clase representa una abstracción visual reusable.
HTML
Copiar < button class = " inline-flex items-center gap-2 px-4 py-3 rounded-lg" >
Guardar
</ button> Cada clase expresa una decisión pequeña. La reutilización puede ocurrir en el componente del framework, no necesariamente en una clase CSS compuesta.
Escala consistente de spacing, color y typography.
Variants para estados y queries.
Generación basada en archivos utilizados.
Arbitrary values para excepciones controladas.
Integración con build y componentes.
Menor necesidad de inventar class names locales.
Sigue produciendo CSS sujeto a layout, cascade, inheritance y browser support.
HTML
Copiar < button class = " bg-brand-600 hover:bg-brand-700 focus-visible:outline-2 disabled:opacity-50" >
Guardar
</ button> Las variants generan selectores y condiciones. El orden final depende de la herramienta, no del orden textual de cada clase en HTML como si fueran declarations inline.
HTML
Copiar < div class = " grid gap-4 md:grid-cols-2 xl:grid-cols-3" > Los breakpoints deben seguir respondiendo al contenido. Una utility no convierte automáticamente un breakpoint predefinido en la decisión correcta.
Una herramienta moderna puede generar container queries, dark mode, reduced motion, forced colors y otras condiciones.
El concepto sigue siendo CSS:
CSS
Copiar @container ( width >= 30rem) { ... }
@media ( prefers-reduced-motion : reduce) { ... } HTML
Copiar < div class = " grid-cols-[minmax(0,2fr)_minmax(18rem,1fr)]" > Son útiles para una relación específica, pero muchos valores arbitrarios repetidos indican tokens o abstracciones faltantes.
HTML
Copiar < div class = " [&>h2]:mt-0" > Permiten selectores locales complejos. Abusar de ellas puede recrear selectores acoplados dentro del markup.
TypeScript
Copiar export const Button = ( { children, variant = 'primary' } ) => {
return (
< button className= { buttonVariants ( { variant } ) } >
{ children}
< / button>
) ;
} ; La reutilización vive en el componente y su API.
No extraigas una clase o componente solo porque una secuencia aparece una vez. Extrae cuando existe un concepto reusable.
Librerías de variants ayudan a mapear props a clases:
Texto
Copiar variant: primary | secondary | danger
size: compact | default
state: loading | disabledLa función debe evitar combinaciones contradictorias y conservar una fuente clara de defaults.
Texto
Copiar px-4 + px-6
text-sm + text-lg
hidden + flexpuede producir resultados dependientes del CSS generado. Una herramienta de merge ayuda, pero no debe reemplazar una API de variants bien diseñada.
No hardcodees la paleta del producto en cada arbitrary value. Conecta Tailwind o cualquier sistema de utilities con tokens semánticos.
Texto
Copiar bg-action-primary
text-on-action
border-subtleLos nombres exactos dependen de la configuración y versión de la herramienta.
TypeScript
Copiar import styles from './card.module.css' ;
< article className= { styles. card} / > Ofrece scope de nombres y permite escribir CSS completo. Es compatible con utilities para casos puntuales.
Aporta estilos según props y co-location. Evalúa:
Runtime.
SSR.
Orden de inyección.
Caching.
Bundle.
Compatibilidad con Server Components.
No toda librería comparte el mismo costo.
TypeScript
Copiar < div style= { { '--progress' : progress } as React. CSSProperties} / > Son apropiados para valores dinámicos específicos. No soportan directamente pseudo-clases o media queries y no deberían reemplazar toda la stylesheet.
Cascade layers, nesting, scope, custom properties y container queries reducen varias razones históricas para depender de preprocesadores.
Sass todavía aporta mixins, loops y tooling cuando el proyecto realmente los necesita.
¿Dónde vive la reutilización?
¿Quién controla tokens?
¿Cómo se expresan states y variants?
¿Existe runtime?
¿Cómo funciona SSR?
¿Cómo se elimina CSS no usado?
¿Cómo se depura el output?
¿Qué conocimientos necesita el equipo?
Aprender Tailwind sin entender CSS.
Creer que utility-first elimina la cascada.
Repetir arbitrary values sin crear tokens.
Crear componentes para ocultar cualquier lista de clases.
Concatenar clases contradictorias.
Usar breakpoints por costumbre.
Mezclar muchas estrategias sin límites.
No inspeccionar el CSS generado.
Toda estrategia termina produciendo estilos del navegador.
Utility-first compone clases pequeñas.
Tailwind automatiza generación y variants.
La reutilización puede vivir en componentes.
Arbitrary values son escapes, no sistema principal.
CSS Modules, CSS-in-JS y vanilla CSS resuelven tradeoffs distintos.
La elección depende del producto y del equipo.
¿Por qué el orden de clases en class="px-4 px-6" no garantiza que px-6 gane?
Respuesta Porque ambas clases corresponden a reglas en una stylesheet; el resultado depende de la cascada y del orden generado de esas reglas, no del orden del atributo class.
Rendimiento, containment y content-visibility explica cómo limitar trabajo de style, layout y paint.