Utilidades de Tailwind
Hoja de referencia de utilidades principales - las clases más usadas y qué cambió en v4.
Busca en todas las páginas de la documentación
Hoja de referencia de utilidades principales - las clases más usadas y qué cambió en v4.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tarjeta de referencia rápida - lista para copiar y pegar.
// Diseño
<div className="flex items-center justify-between gap-4">
<div className="grid grid-cols-3 gap-6">
<div className="absolute top-0 right-0">
<div className="sticky top-4">
// Tamaño
<div className="h-screen w-full max-w-lg min-h-0">
<div className="size-12"> {/* ancho Y alto */}
// Espaciado
<div className="p-4 px-6 py-2 pt-8">
<div className="m-auto mx-4 my-2 mt-0">
<div className="space-y-4"> {/* separación entre hijos */}
// Tipografía
<p className="text-sm font-medium leading-tight tracking-wide">
<p className="text-gray-600 text-balance truncate">
<p className="line-clamp-3 antialiased">
// Colores
<div className="bg-blue-500 text-white border-gray-200">
<div className="bg-blue-500/50"> {/* 50% de opacidad */}
// Bordes y radio
<div className="rounded-lg border border-gray-200 shadow-md">
<div className="ring-2 ring-blue-500 ring-offset-2">
<div className="divide-y divide-gray-100">
// Interactividad
<button className="cursor-pointer hover:bg-blue-600 focus:outline-none focus-visible:ring-2">
<div className="pointer-events-none select-none">Cuándo usarlo: Cada vez que escribes un componente. Estas cubren el 90% de las necesidades de estilo.
export function ProductCard({
name,
price,
image,
badge,
}: {
name: string;
price: number;
image: string;
badge?: string;
}) {
return (
<article className="group relative overflow-hidden rounded-xl border border-gray-200 bg-white shadow-sm transition-shadow hover:shadow-lg">
{/* Imagen */}
<div className="aspect-square overflow-hidden">
<img
src={image}
alt={name}
className="size-full object-cover transition-transform duration-300 group-hover:scale-105"
/>
</div>
{/* Insignia */}
{badge && (
<span className="absolute top-3 left-3 rounded-full bg-blue-500 px-2.5 py-0.5 text-xs font-semibold text-white">
{badge}
</span>
)}
{/* Contenido */}
<div className="space-y-1.5 p-4">
<h3 className="truncate text-sm font-medium text-gray-900">{name}</h3>
<p className="text-lg font-bold text-gray-900">
${price.toFixed(2)}
</p>
<button className="mt-2 w-full rounded-lg bg-gray-900 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-gray-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 active:scale-[0.98]">
Añadir al carrito
</button>
</div>
</article>
);
}Qué demuestra esto:
group + group-hover:* para efectos hover entre padre e hijoaspect-square para mantener la proporción de la imagensize-full (atajo de w-full h-full)transition-* para efectos hover suavesfocus-visible: para anillos de foco solo con tecladoactive:scale-[0.98] para feedback al presionartruncate para desbordamiento de textop-4 = padding: 1rem)w-[347px], bg-[#1da1f2], grid-cols-[200px_1fr]dark:hover:bg-blue-600 = modo oscuro + hover@layer, @property, anidamiento nativoNuevo en v4 - cambios clave:
/* 1. inset-shadow e inset-ring (reemplaza hacks de box-shadow) */
.card { @apply inset-shadow-sm inset-ring inset-ring-gray-200; }
/* 2. La opacidad del color usa sintaxis con barra (igual que v3) */
.overlay { @apply bg-black/50; }
/* 3. Variante not-* */
.item { @apply not-last:border-b; }
/* 4. Variante in-* para el estado del padre */
.child { @apply in-[.open]:block; }
/* 5. Nuevas utilidades size-* */
.avatar { @apply size-10; /* = w-10 h-10 */ }
/* 6. text-balance y text-pretty */
.heading { @apply text-balance; }
.paragraph { @apply text-pretty; }Patrones de Flexbox:
// Contenido centrado
<div className="flex min-h-screen items-center justify-center">
// Diseño con barra lateral
<div className="flex">
<aside className="w-64 shrink-0" />
<main className="min-w-0 flex-1" />
</div>
// Espacio entre elementos con wrap
<div className="flex flex-wrap items-center justify-between gap-4">
// Pila con empuje por margin auto
<nav className="flex flex-col">
<a>Home</a>
<a>About</a>
<a className="mt-auto">Settings</a> {/* empujado hacia abajo */}
</nav>Patrones de Grid:
// Grid responsivo con auto-fill
<div className="grid grid-cols-[repeat(auto-fill,minmax(250px,1fr))] gap-4">
// Áreas nombradas
<div className="grid grid-cols-[250px_1fr] grid-rows-[auto_1fr_auto] [grid-template-areas:'sidebar_header''sidebar_main''sidebar_footer']">
// Subgrid (v4)
<div className="grid grid-cols-subgrid col-span-3">// Composición de utilidades con tipado seguro usando cva o clsx
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
function cn(...inputs: (string | undefined | false | null)[]) {
return twMerge(clsx(inputs));
}
// Uso
<div className={cn(
"rounded border p-4",
isActive && "border-blue-500 bg-blue-50",
disabled && "opacity-50 pointer-events-none",
)} />El orden de clases no determina la especificidad - p-4 p-2 no garantiza que gane p-2. Ambas tienen la misma especificidad; el orden en el código fuente CSS decide. Solución: Usa tailwind-merge para resolver conflictos: twMerge("p-4 p-2") devuelve "p-2".
Los valores arbitrarios necesitan pistas de tipo correctas - bg-[--brand] es ambiguo. Solución: Usa bg-[color:--brand] para indicarle a Tailwind que es un valor de color.
min-w-0 en hijos flex - Los hijos flex tienen por defecto min-width: auto, lo que provoca overflow. Solución: Añade min-w-0 a los hijos flex que deban encogerse.
truncate necesita una restricción de ancho - truncate sin un ancho en el padre no hace nada. Solución: Asegúrate de que el elemento o un padre tenga un ancho o max-width definido.
space-y-* con hijos renderizados condicionalmente - Los hijos ocultos siguen recibiendo márgenes. Solución: Usa gap-* con flex/grid en su lugar.
| Alternativa | Cuándo usarla | Cuándo no usarla |
|---|---|---|
| Estilos en línea | Valores dinámicos puntuales (p. ej., style={{ width: computed }}) | Tienes patrones estáticos y repetitivos |
| CSS Modules | Necesitas CSS con alcance para una biblioteca de componentes | Prefieres un flujo de trabajo utility-first |
| Styled Components | Quieres CSS-in-JS con theming dinámico | Quieres cero CSS en tiempo de ejecución |
| Panda CSS | Quieres tokens de utilidades con tipado seguro y cero runtime | Prefieres la DX basada en clases de Tailwind |
Establece tanto width como height en 3rem - un atajo de w-12 h-12.
Usa la sintaxis con barra: bg-blue-500/50. El número después de / es el porcentaje de opacidad.
group a un elemento padregroup-hover:* en los hijos para estilizarlos cuando el padre recibe hoverfocus-visible: solo se activa con foco de teclado, no con clics del ratón. Esto evita anillos de foco no deseados después de hacer clic en un botón.
Usa la sintaxis de corchetes: w-[347px], bg-[#1da1f2], grid-cols-[200px_1fr].
El orden de clases en la cadena className no determina la especificidad CSS. Ambas tienen la misma especificidad, así que el orden en el código fuente CSS decide. Usa twMerge("p-4 p-2") para resolver de forma fiable a p-2.
truncate requiere que el elemento o un padre tenga una restricción de width o max-width definida. Sin ella, no hay nada contra lo que truncar.
Los hijos flex tienen por defecto min-width: auto, lo que impide que se encojan por debajo del tamaño de su contenido. min-w-0 permite un encogimiento correcto y evita overflow.
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
function cn(...inputs: (string | undefined | false | null)[]) {
return twMerge(clsx(inputs));
}Combina nombres de clase condicionales y resuelve conflictos de Tailwind.
text-balance - equilibra la longitud de las líneas en encabezados para que ninguna sea mucho más corta que otratext-pretty - evita palabras huérfanas al final de los párrafosLos modificadores se encadenan de izquierda a derecha. dark:hover:bg-blue-600 significa "en modo oscuro, al hacer hover, aplica bg-blue-600."
<div className={cn(
"rounded border p-4",
isActive && "border-blue-500 bg-blue-50",
disabled && "opacity-50 pointer-events-none",
)} />Los valores falsy se filtran con clsx antes de que twMerge resuelva los conflictos.
Revisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥