Una chuleta de Tailwind CSS v4 con buscador: escribe cualquier clase o palabra y verás el CSS exacto que genera v4, desde múltiplos de var(--spacing) hasta tokens de color en OKLCH. También cubre los tokens de @theme, los breakpoints, las container queries, cajas flex y grid en vivo, la paleta de colores completa, el modo oscuro y los cambios de nombre de v3 a v4.
Esta chuleta cubre Tailwind CSS v4 (v4.3 es la versión actual en el momento de escribir esto, octubre de 2026). Para cada clase muestra el CSS que v4 escribe de verdad, algo importante porque v4 cambió la forma de producir los valores: el espaciado es un múltiplo de una única variable --spacing , los colores son variables --color-* definidas en OKLCH, y tamaños como el radio, la sombra y el texto salen de variables de tema con nombre. Escribe en la caja para filtrar. La búsqueda funciona con nombres de clase, con el CSS que generan y con palabras sencillas como "center", "gradient" o "sticky".
Se muestran las 243
| Clase | CSS que genera en v4 |
|---|---|
| Layout y display | |
block | display: block; |
inline-block | display: inline-block; |
inline | display: inline; |
flex | display: flex; |
inline-flex | display: inline-flex; |
grid | display: grid; |
inline-grid | display: inline-grid; |
contents | display: contents; |
hidden | display: none; |
container | width: 100%; plus max-width: var(--breakpoint-sm) at sm, and so on for each breakpoint |
box-border | box-sizing: border-box; |
box-content | box-sizing: content-box; |
static | position: static; |
relative | position: relative; |
absolute | position: absolute; |
fixed | position: fixed; |
sticky | position: sticky; |
inset-0 | inset: calc(var(--spacing) * 0); |
inset-x-0 | inset-inline: calc(var(--spacing) * 0); |
top-4 | top: calc(var(--spacing) * 4); /* 1rem */ |
-top-2 | top: calc(var(--spacing) * -2); |
left-1/2 | left: calc(1/2 * 100%); |
z-10 | z-index: 10; |
z-50 | z-index: 50; |
isolate | isolation: isolate; |
overflow-hidden | overflow: hidden; |
overflow-auto | overflow: auto; |
overflow-x-auto | overflow-x: auto; |
aspect-video | aspect-ratio: var(--aspect-video); /* 16 / 9 */ |
aspect-square | aspect-ratio: 1 / 1; |
object-cover | object-fit: cover; |
object-contain | object-fit: contain; |
visible | visibility: visible; |
invisible | visibility: hidden; |
sr-only | position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border-width: 0; |
| Flexbox | |
flex-row | flex-direction: row; |
flex-col | flex-direction: column; |
flex-row-reverse | flex-direction: row-reverse; |
flex-wrap | flex-wrap: wrap; |
flex-nowrap | flex-wrap: nowrap; |
flex-1 | flex: 1; |
flex-auto | flex: auto; |
flex-initial | flex: 0 auto; |
flex-none | flex: none; |
grow | flex-grow: 1; |
grow-0 | flex-grow: 0; |
shrink-0 | flex-shrink: 0; |
basis-64 | flex-basis: calc(var(--spacing) * 64); |
basis-1/3 | flex-basis: calc(1/3 * 100%); |
order-2 | order: 2; |
order-first | order: -9999; |
order-last | order: 9999; |
| Alineación y gap | |
justify-start | justify-content: flex-start; |
justify-center | justify-content: center; |
justify-end | justify-content: flex-end; |
justify-between | justify-content: space-between; |
justify-around | justify-content: space-around; |
justify-evenly | justify-content: space-evenly; |
items-start | align-items: flex-start; |
items-center | align-items: center; |
items-end | align-items: flex-end; |
items-baseline | align-items: baseline; |
items-stretch | align-items: stretch; |
self-center | align-self: center; |
self-end | align-self: flex-end; |
content-center | align-content: center; |
place-items-center | place-items: center; |
place-content-center | place-content: center; |
justify-items-center | justify-items: center; |
gap-4 | gap: calc(var(--spacing) * 4); /* 1rem */ |
gap-x-6 | column-gap: calc(var(--spacing) * 6); |
gap-y-2 | row-gap: calc(var(--spacing) * 2); |
| Grid | |
grid-cols-3 | grid-template-columns: repeat(3, minmax(0, 1fr)); |
grid-cols-12 | grid-template-columns: repeat(12, minmax(0, 1fr)); |
grid-cols-[200px_1fr] | grid-template-columns: 200px 1fr; |
grid-cols-subgrid | grid-template-columns: subgrid; |
grid-rows-3 | grid-template-rows: repeat(3, minmax(0, 1fr)); |
col-span-2 | grid-column: span 2 / span 2; |
col-span-full | grid-column: 1 / -1; |
col-start-2 | grid-column-start: 2; |
row-span-2 | grid-row: span 2 / span 2; |
grid-flow-col | grid-auto-flow: column; |
grid-flow-dense | grid-auto-flow: dense; |
auto-rows-fr | grid-auto-rows: minmax(0, 1fr); |
auto-cols-max | grid-auto-columns: max-content; |
| Espaciado | |
p-4 | padding: calc(var(--spacing) * 4); /* 1rem */ |
p-px | padding: 1px; |
p-[13px] | padding: 13px; |
p-(--card-pad) | padding: var(--card-pad); |
px-6 | padding-inline: calc(var(--spacing) * 6); |
py-2 | padding-block: calc(var(--spacing) * 2); |
pt-8 | padding-top: calc(var(--spacing) * 8); |
ps-4 | padding-inline-start: calc(var(--spacing) * 4); |
m-0 | margin: calc(var(--spacing) * 0); |
mx-auto | margin-inline: auto; |
mt-6 | margin-top: calc(var(--spacing) * 6); |
-mt-2 | margin-top: calc(var(--spacing) * -2); |
ms-auto | margin-inline-start: auto; |
space-y-4 | margin-block-end: calc(var(--spacing) * 4) on every child except the last (selector: > :not(:last-child)) |
space-x-2 | margin-inline-end: calc(var(--spacing) * 2) on every child except the last |
| Tamaño | |
w-64 | width: calc(var(--spacing) * 64); /* 16rem */ |
w-full | width: 100%; |
w-1/2 | width: calc(1/2 * 100%); |
w-screen | width: 100vw; |
w-fit | width: fit-content; |
w-auto | width: auto; |
size-10 | width: calc(var(--spacing) * 10); height: calc(var(--spacing) * 10); |
h-12 | height: calc(var(--spacing) * 12); |
h-dvh | height: 100dvh; |
h-screen | height: 100vh; |
min-h-screen | min-height: 100vh; |
min-w-0 | min-width: calc(var(--spacing) * 0); |
max-w-md | max-width: var(--container-md); /* 28rem */ |
max-w-7xl | max-width: var(--container-7xl); /* 80rem */ |
max-w-prose | max-width: 65ch; |
max-w-screen-lg | max-width: var(--breakpoint-lg); |
| Tipografía | |
text-xs | font-size: var(--text-xs); /* 0.75rem */ line-height: var(--tw-leading, var(--text-xs--line-height)); |
text-sm | font-size: var(--text-sm); /* 0.875rem */ line-height: var(--tw-leading, var(--text-sm--line-height)); |
text-base | font-size: var(--text-base); /* 1rem */ line-height: var(--tw-leading, var(--text-base--line-height)); |
text-xl | font-size: var(--text-xl); /* 1.25rem */ line-height: var(--tw-leading, var(--text-xl--line-height)); |
text-4xl | font-size: var(--text-4xl); /* 2.25rem */ line-height: var(--tw-leading, var(--text-4xl--line-height)); |
text-sm/6 | font-size: var(--text-sm); line-height: calc(var(--spacing) * 6); |
font-sans | font-family: var(--font-sans); |
font-mono | font-family: var(--font-mono); |
font-medium | font-weight: var(--font-weight-medium); /* 500 */ |
font-semibold | font-weight: var(--font-weight-semibold); /* 600 */ |
font-bold | font-weight: var(--font-weight-bold); /* 700 */ |
leading-tight | line-height: var(--leading-tight); /* 1.25 */ |
leading-6 | line-height: calc(var(--spacing) * 6); |
tracking-tight | letter-spacing: var(--tracking-tight); /* -0.025em */ |
tracking-wide | letter-spacing: var(--tracking-wide); |
text-left | text-align: left; |
text-center | text-align: center; |
text-right | text-align: right; |
uppercase | text-transform: uppercase; |
capitalize | text-transform: capitalize; |
italic | font-style: italic; |
underline | text-decoration-line: underline; |
no-underline | text-decoration-line: none; |
underline-offset-4 | text-underline-offset: 4px; |
decoration-2 | text-decoration-thickness: 2px; |
truncate | overflow: hidden; text-overflow: ellipsis; white-space: nowrap; |
line-clamp-3 | overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; |
text-balance | text-wrap: balance; |
text-pretty | text-wrap: pretty; |
whitespace-nowrap | white-space: nowrap; |
wrap-break-word | overflow-wrap: break-word; /* added in v4.1 */ |
tabular-nums | font-variant-numeric: tabular-nums; |
antialiased | -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; |
| Color y fondos | |
text-blue-600 | color: var(--color-blue-600); /* oklch(54.6% 0.245 262.881) */ |
bg-white | background-color: var(--color-white); /* #fff */ |
bg-slate-900 | background-color: var(--color-slate-900); |
bg-black/50 | background-color: color-mix(in oklab, var(--color-black) 50%, transparent); |
bg-[#4f98fb] | background-color: #4f98fb; |
bg-(--brand) | background-color: var(--brand); |
text-current | color: currentColor; |
bg-transparent | background-color: transparent; |
border-gray-200 | border-color: var(--color-gray-200); |
fill-current | fill: currentColor; |
accent-blue-600 | accent-color: var(--color-blue-600); |
caret-pink-500 | caret-color: var(--color-pink-500); |
bg-linear-to-r | background-image: linear-gradient(to right in oklab, var(--tw-gradient-stops)); /* simplified */ |
from-blue-500 | --tw-gradient-from: var(--color-blue-500); /* first stop */ |
to-violet-500 | --tw-gradient-to: var(--color-violet-500); |
bg-radial | background-image: radial-gradient(...stops); /* new in v4 */ |
bg-cover | background-size: cover; |
bg-center | background-position: center; |
bg-no-repeat | background-repeat: no-repeat; |
bg-clip-text | background-clip: text; |
| Bordes, radios, rings y outlines | |
border | border-style: var(--tw-border-style); border-width: 1px; /* color is currentColor in v4 */ |
border-2 | border-style: var(--tw-border-style); border-width: 2px; |
border-t | border-top-style: var(--tw-border-style); border-top-width: 1px; |
border-dashed | --tw-border-style: dashed; border-style: dashed; |
rounded-xs | border-radius: var(--radius-xs); /* 0.125rem */ |
rounded-sm | border-radius: var(--radius-sm); /* 0.25rem */ |
rounded-md | border-radius: var(--radius-md); /* 0.375rem */ |
rounded-lg | border-radius: var(--radius-lg); /* 0.5rem */ |
rounded-2xl | border-radius: var(--radius-2xl); /* 1rem */ |
rounded-full | border-radius: calc(infinity * 1px); |
rounded-t-lg | border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg); |
divide-y | border-bottom-width: 1px on every child except the last (selector: > :not(:last-child)) |
ring-1 | box-shadow: 0 0 0 1px currentColor; /* simplified; v4 default ring width is 1px */ |
ring-3 | box-shadow: 0 0 0 3px currentColor; /* the old v3 ring */ |
ring-blue-500 | --tw-ring-color: var(--color-blue-500); |
ring-offset-2 | --tw-ring-offset-width: 2px; |
outline | outline-style: var(--tw-outline-style); outline-width: 1px; |
outline-2 | outline-style: var(--tw-outline-style); outline-width: 2px; |
outline-offset-2 | outline-offset: 2px; |
outline-hidden | outline: 2px solid transparent; outline-offset: 2px; /* still visible in forced colors */ |
outline-none | --tw-outline-style: none; outline-style: none; |
| Efectos y filtros | |
shadow-2xs | box-shadow: 0 1px rgb(0 0 0 / 0.05); |
shadow-xs | box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); |
shadow-sm | box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); |
shadow-md | box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); |
shadow-lg | box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); |
shadow-2xl | box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); |
shadow-none | box-shadow: 0 0 #0000; |
inset-shadow-sm | box-shadow: inset 0 2px 4px rgb(0 0 0 / 0.05); /* new in v4 */ |
opacity-50 | opacity: 50%; |
mix-blend-multiply | mix-blend-mode: multiply; |
blur-sm | filter: blur(var(--blur-sm)); /* 8px */ |
blur-xs | filter: blur(var(--blur-xs)); /* 4px */ |
backdrop-blur-md | backdrop-filter: blur(var(--blur-md)); /* 12px, frosted glass */ |
grayscale | filter: grayscale(100%); |
| Transiciones, animación y transformaciones | |
transition | transition-property: color, background-color, border-color, outline-color, opacity, box-shadow, transform, translate, scale, rotate, filter and more; transition-duration: 150ms; |
transition-colors | transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke and gradient stops; 150ms |
duration-200 | transition-duration: 200ms; |
ease-out | transition-timing-function: var(--ease-out); /* cubic-bezier(0, 0, 0.2, 1) */ |
animate-spin | animation: var(--animate-spin); /* spin 1s linear infinite */ |
animate-pulse | animation: var(--animate-pulse); |
motion-reduce:animate-none | @media (prefers-reduced-motion: reduce) { animation: none; } |
scale-95 | --tw-scale-x: 95%; --tw-scale-y: 95%; scale: var(--tw-scale-x) var(--tw-scale-y); |
rotate-45 | rotate: 45deg; |
translate-x-4 | --tw-translate-x: calc(var(--spacing) * 4); translate: var(--tw-translate-x) var(--tw-translate-y); |
-translate-y-1/2 | --tw-translate-y: calc(calc(1/2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); |
| Interactividad | |
cursor-pointer | cursor: pointer; /* v4 buttons default to cursor: default */ |
cursor-not-allowed | cursor: not-allowed; |
pointer-events-none | pointer-events: none; |
select-none | user-select: none; |
appearance-none | appearance: none; |
scroll-smooth | scroll-behavior: smooth; |
snap-x | scroll-snap-type: x var(--tw-scroll-snap-strictness); |
snap-start | scroll-snap-align: start; |
scroll-mt-20 | scroll-margin-top: calc(var(--spacing) * 20); |
resize-y | resize: vertical; |
touch-manipulation | touch-action: manipulation; |
| Variantes de estado y de media | |
hover:bg-blue-700 | @media (hover: hover) { &:hover { background-color: var(--color-blue-700); } } |
focus-visible:outline-2 | &:focus-visible { outline-width: 2px; ... } |
active:scale-95 | &:active { scale: 95%; } |
disabled:opacity-50 | &:disabled { opacity: 50%; } |
aria-disabled:opacity-50 | &[aria-disabled="true"] { opacity: 50%; } |
group-hover:underline | .group:hover & { text-decoration-line: underline; } (inside @media (hover: hover)) |
peer-checked:bg-blue-600 | .peer:checked ~ & { background-color: var(--color-blue-600); } |
md:flex | @media (width >= 48rem) { display: flex; } |
max-md:hidden | @media (width < 48rem) { display: none; } |
@md:flex-row | @container (width >= 28rem) { flex-direction: row; } |
dark:bg-slate-900 | @media (prefers-color-scheme: dark) { background-color: var(--color-slate-900); } |
print:hidden | @media print { display: none; } |
motion-safe:animate-spin | @media (prefers-reduced-motion: no-preference) { ... } |
*:p-2 | :where(& > *) { padding: calc(var(--spacing) * 2); } |
not-last:mb-2 | &:not(:last-child) { margin-bottom: ... } |
supports-[display:grid]:grid | @supports (display: grid) { display: grid; } |
bg-red-500! | background-color: var(--color-red-500) !important; |
Cómo leer la tabla: calc(var(--spacing) * 4) equivale a 1rem porque el valor por defecto de --spacing es 0.25rem. Cambia esa única variable en @theme y todos los padding, margin, gap, width y height que usan la escala numérica cambian con ella. Cuando el CSS generado es largo (degradados, rings, transiciones), la tabla muestra una versión simplificada y lo indica.
En v4 hay cuatro formas de dar un valor a una utilidad, y saber cuál estás usando explica la mayoría de las sorpresas:
p-4, w-64, gap-3. Sirve cualquier número entero, y también los cuartos de paso como p-2.5, sin configuración. El valor es calc(var(--spacing) * n).rounded-lg, shadow-md, text-xl, max-w-md. Cada una lee una variable como --radius-lg o --container-md.p-[13px], grid-cols-[200px_1fr], bg-[#4f98fb]. Los guiones bajos sustituyen a los espacios.bg-(--brand) es la forma abreviada de v4 para bg-[var(--brand)]. En v3 escribías bg-[--brand].Las fracciones como w-1/2 se convierten en calc(1/2 * 100%), y un sufijo de opacidad como bg-black/50 se convierte en un color-mix() con transparente, así que funciona con cualquier formato de color.
En v4 el sistema de diseño se configura en CSS. Las variables declaradas dentro de @theme se convierten a la vez en propiedades personalizadas de CSS en :root y en el origen de las clases de utilidad. El prefijo de la variable decide a qué utilidades alimenta:
@import "tailwindcss";
@theme {
--font-display: "Satoshi", sans-serif; /* font-display */
--color-brand-500: oklch(65% 0.17 255); /* bg-brand-500, text-brand-500 ... */
--breakpoint-3xl: 120rem; /* 3xl: variant */
--spacing: 0.25rem; /* p-4 = 1rem */
--radius-card: 0.875rem; /* rounded-card */
}
| Espacio de nombres | Alimenta a | Ejemplo |
|---|---|---|
--color-* | todas las utilidades de color (bg, text, border, fill, ring, color de sombra...) | bg-red-500 |
--spacing | padding, margin, gap, width, height, inset, translate | px-4 |
--font-* | familia tipográfica | font-sans |
--text-* | tamaño de fuente (más el opcional --text-*--line-height) | text-xl |
--font-weight-* | peso de fuente | font-bold |
--tracking-* / --leading-* | espaciado entre letras / interlineado | tracking-wide |
--breakpoint-* | variantes responsive | sm:* |
--container-* | variantes de container query y max-w-* | @sm:*, max-w-md |
--radius-* | radio del borde | rounded-sm |
--shadow-*, --inset-shadow-*, --drop-shadow-* | sombras | shadow-md |
--blur-* | desenfoque y desenfoque de fondo | blur-md |
--ease-* / --animate-* | funciones de temporización / animaciones | ease-out, animate-spin |
--perspective-* / --aspect-* | perspectiva 3D / relación de aspecto | perspective-near, aspect-video |
Para quitar un espacio de nombres completo por defecto, ponlo primero en initial , por ejemplo --color-*: initial;, y después declara solo tus propios colores. Si todavía tienes una configuración en JavaScript, v4 puede cargarla con @config "./tailwind.config.js";, pero las opciones corePlugins, safelist y separator no son compatibles.
Los breakpoints son mobile first: una clase sin prefijo se aplica en cualquier ancho, y md:flex se aplica a partir de 48rem. v4 los escribe con la sintaxis de rango width >= ....
| Prefijo | Ancho mínimo | CSS | Por debajo (max-*) |
|---|---|---|---|
sm: | 40rem (640px) | @media (width >= 40rem) | max-sm: = @media (width < 40rem) |
md: | 48rem (768px) | @media (width >= 48rem) | max-md: |
lg: | 64rem (1024px) | @media (width >= 64rem) | max-lg: |
xl: | 80rem (1280px) | @media (width >= 80rem) | max-xl: |
2xl: | 96rem (1536px) | @media (width >= 96rem) | max-2xl: |
Combínalos para apuntar a un rango: md:max-xl:flex solo se aplica desde 48rem hasta 80rem (sin incluirlo). Para un breakpoint puntual usa min-[900px]:grid o max-[600px]:hidden. Añade o cambia breakpoints con --breakpoint-* en @theme, y mantenlos todos en rem para que se ordenen correctamente.
Las container queries vienen integradas en v4 (en v3 necesitaban un plugin). Marca un elemento padre con @containery después da estilo a los hijos con @sm:, @md: y similares. Reaccionan al ancho del padre en lugar del de la ventana, que es justo lo que necesitas para una tarjeta que aparece tanto en una barra lateral como en una columna principal ancha.
<div class="@container">
<article class="flex flex-col @md:flex-row gap-4">
<img class="w-full @md:w-48 rounded-lg" src="..." alt="">
<div>...</div>
</article>
</div>
| Variante | Ancho del contenedor | Variante | Ancho del contenedor |
|---|---|---|---|
@3xs | 16rem (256px) | @2xl | 42rem (672px) |
@2xs | 18rem (288px) | @3xl | 48rem (768px) |
@xs | 20rem (320px) | @4xl | 56rem (896px) |
@sm | 24rem (384px) | @5xl | 64rem (1024px) |
@md | 28rem (448px) | @6xl | 72rem (1152px) |
@lg | 32rem (512px) | @7xl | 80rem (1280px) |
@xl | 36rem (576px) |
Cada una se compila a @container (width >= ...). Usa @max-md: para "por debajo", combina @sm:@max-md: para un rango, pon nombre a los contenedores con @container/sidebar y apúntalos con @md/sidebar:, y usa tamaños arbitrarios como @min-[475px]:. Ojo: los tamaños de contenedor no coinciden con los de los breakpoints: @md es 28rem mientras que md: es 48rem.
Elige un layout aquí abajo y mira cómo se mueven las cajas. La cadena de clases se actualiza al hacer clic, así que puedes copiarla directamente en tu marcado.
Los patrones que más vas a usar:
flex items-center justify-between: fila de barra de navegaciónflex items-center justify-center (o grid place-items-center): centrar un elementogrid grid-cols-3 gap-2 con col-span-2shrink-0 en el elemento fijo, flex-1 en el elemento que ocupa el resto| Objetivo | Clases |
|---|---|
| Cuadrícula de tarjetas responsive sin breakpoints | grid grid-cols-[repeat(auto-fill,minmax(16rem,1fr))] gap-6 |
| Barra lateral más contenido | grid md:grid-cols-[16rem_1fr] gap-8 |
| Footer fijado al fondo de una página corta | flex min-h-dvh flex-col en el contenedor, flex-1 en main |
| Texto que se trunca dentro de una fila flex | min-w-0 en el hijo flex, truncate en el texto |
| Apilado en móvil, en fila en escritorio | flex flex-col md:flex-row gap-4 |
| Empujar el último elemento a la derecha | ms-auto (o ml-auto) en ese elemento |
v4 define la paleta por defecto en OKLCH, que puede mostrar colores más saturados en pantallas de gama amplia. Cada muestra de abajo está pintada con el valor exacto del archivo de tema de Tailwind; haz clic en una para copiar su valor oklch() . Los tonos van de 50 a 950. Las paletas marcadas con * (mauve, olive, mist y taupe) se añadieron en v4.2.0, así que no existen en versiones anteriores de v4. El negro y el blanco son #000 y #fff.
Úsalos como bg-sky-500, text-sky-500/80 o, en tu propio CSS, var(--color-sky-500). Para comprobar si una combinación es legible, pásala por el comprobador de contraste de color, y para crear una escala propia en el mismo formato prueba el generador de paletas de colores de Tailwind.
Por defecto, dark: sigue al sistema operativo mediante @media (prefers-color-scheme: dark). Para controlarlo desde una clase o un atributo (para un interruptor manual), sobrescribe la variante en tu CSS con @custom-variant. Ya no existe la clave de configuración darkMode .
/* Class strategy: <html class="dark"> */
@custom-variant dark (&:where(.dark, .dark *));
/* Or a data attribute: <html data-theme="dark"> */
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
<div class="bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100">...</div>
Con un interruptor manual, aplica la clase antes de que se pinte la página (un pequeño script en línea en <head> que lea la opción guardada) para que los visitantes no vean un destello del tema equivocado. Una tercera opción es prescindir por completo de las clases dark: : define tokens semánticos como --color-surface en @theme y cambia sus valores bajo .dark, para que una sola clase como bg-surface funcione en ambos temas.
Proceden de la guía oficial de actualización. Los cambios de nombre son lo más importante, porque los nombres antiguos siguen existiendo y producen sin avisar un resultado distinto (más pequeño).
| v3 | v4 | Motivo |
|---|---|---|
shadow-sm | shadow-xs | La escala bajó un paso para que todos los tamaños tengan nombre |
shadow | shadow-sm | Mismo desplazamiento |
drop-shadow-sm / drop-shadow | drop-shadow-xs / drop-shadow-sm | Mismo desplazamiento |
blur-sm / blur | blur-xs / blur-sm | Mismo desplazamiento (también backdrop-blur-*) |
rounded-sm | rounded-xs | Mismo desplazamiento |
rounded | rounded-sm | Mismo desplazamiento |
outline-none | outline-hidden | v4 outline-none ahora sí establece outline-style: none |
ring (3px, blue-500) | ring-3 más un color | Un ring sin más ahora es de 1px en currentColor |
outline outline-2 | outline-2 | Las utilidades de ancho ahora aplican por sí mismas un estilo sólido |
bg-opacity-50 (y text-, border-, ring-, divide-, placeholder-opacity) | bg-black/50 | Eliminado; usa el modificador con barra |
flex-shrink-0 / flex-grow | shrink-0 / grow | Alias eliminados |
overflow-ellipsis | text-ellipsis | Alias eliminado |
decoration-slice / decoration-clone | box-decoration-slice / box-decoration-clone | Alias eliminados |
bg-[--brand] | bg-(--brand) | Nueva forma abreviada para variables CSS |
!bg-red-500 | bg-red-500! | El important va al final (la forma antigua está obsoleta) |
first:*:pt-0 | *:first:pt-0 | Las variantes combinadas ahora se leen de izquierda a derecha |
tw-flex (prefijo) | tw:flex | Los prefijos parecen una variante y van primero |
Cambios de comportamiento sin cambio de nombre, que pillan a la gente al actualizar:
currentColor en lugar de gray-200, así que un border sin más se ve oscuro. Añade un color como border-gray-200.hover: va envuelto en @media (hover: hover), así que un toque ya no deja pegados los estilos de hover.cursor: default como hace el navegador. Añade cursor-pointer si quieres la manita.> :not(:last-child) y el margen pasó al lado final. Si el espaciado se ve raro, cambia a flex o grid con gap.center y padding ya no existen; extiéndelo con @utility container { margin-inline: auto; padding-inline: 2rem; }.bg-linear-to-r y añade bg-radial y bg-conic.La herramienta oficial npx @tailwindcss/upgrade resuelve automáticamente la mayoría de los cambios de nombre. Ejecútala en una rama limpia y revisa el diff, porque no puede saber qué clases shadow querías que siguieran viéndose igual.
Esta página tiene estilos de impresión: las cajas de búsqueda y los botones se ocultan, las tablas usan una fuente más pequeña y la cuadrícula de colores mantiene juntas sus muestras. En la mayoría de los navegadores, activa "Gráficos de fondo" en el diálogo de impresión o las muestras saldrán en blanco. Si antes filtraste la tabla, solo se imprimen las filas visibles, una forma rápida de hacer una hoja de una página solo con las utilidades que usas.
La misma variante print: funciona en tus propios proyectos: print:hidden en la navegación, print:text-black en el texto claro y print:break-inside-avoid en las tarjetas mantienen legibles las páginas impresas.
v4 se configura en CSS. Importas Tailwind con @import "tailwindcss" y declaras los tokens de diseño dentro de un bloque @theme, como --color-brand-500 o --breakpoint-3xl. Todavía se puede cargar una configuración en JavaScript con la directiva @config, pero las opciones corePlugins, safelist y separator no son compatibles.
sm es 40rem (640px), md es 48rem (768px), lg es 64rem (1024px), xl es 80rem (1280px) y 2xl es 96rem (1536px). Son mobile first, así que md:flex se aplica desde 48rem en adelante. Usa max-md: para estilos por debajo de un breakpoint y combínalos, como md:max-xl:, para un rango.
Las escalas de sombra, radio y desenfoque bajaron un paso. shadow-sm de v3 es shadow-xs en v4, shadow de v3 es shadow-sm en v4, rounded-sm de v3 es rounded-xs en v4 y rounded de v3 es rounded-sm en v4. Los nombres antiguos siguen compilando, así que no hay ningún error; simplemente producen el tamaño inmediatamente inferior.
Añade @custom-variant dark (&:where(.dark, .dark *)); a tu CSS. Las utilidades dark: se aplicarán siempre que un ancestro tenga la clase dark. Si prefieres un atributo data, usa [data-theme=dark] en el selector.
No. Las container queries vienen integradas. Pon @container en el padre y usa variantes como @sm:, @md: y @max-md: en sus hijos. Los tamaños de contenedor empiezan en @3xs (16rem) y son distintos de los breakpoints de página; por ejemplo, @md es 28rem.
padding: calc(var(--spacing) * 4). Con el --spacing por defecto de 0.25rem, eso es 1rem (16px con el tamaño de fuente por defecto). Cualquier número entero funciona en la escala de espaciado sin configuración, y al cambiar --spacing se reescalan todos a la vez.
Display
Items
Dirección
Wrap
Eje principal
Columnas
Eje transversal
Gap
Copiado
Copiar clases
Imprimir esta chuleta
Empieza gratis · Sin tarjeta de crédito