Busca en todas las páginas de la documentación
Instala Tailwind CSS v4, configúralo con el enfoque CSS-first, configura @theme y usa @import "tailwindcss".
Tarjeta de receta de referencia rápida — lista para copiar y pegar.
# Instala Tailwind CSS v4 con Next.js
npm install tailwindcss @tailwindcss/postcss postcss
# O con Vite
npm install tailwindcss @tailwindcss/vite/* app/globals.css — la ÚNICA configuración que necesitas */
@import "tailwindcss";
/* Valores de tema personalizados */
@theme {
--color-brand: #3b82f6;
--color-brand-dark: #1d4ed8;
--font-family-heading: "Inter", sans-serif;
--breakpoint-3xl: 1920px;
}// postcss.config.mjs (Next.js)
export default {
plugins: {
"@tailwindcss/postcss": {},
},
};// vite.config.ts (Vite)
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [tailwindcss()],
});Cuándo usarlo: Al inicio de cada proyecto nuevo que use Tailwind CSS v4 — la configuración es más simple que en v3, sin necesidad de tailwind.config.js.
/* app/globals.css — configuración completa del proyecto */
@import "tailwindcss";
/* Detección de fuentes — indica a Tailwind dónde están tus clases */
@source "../components/**/*.tsx";
@source "../lib/**/*.ts";
/* Tema personalizado */
@theme {
/* Colores */
--color-primary: #2563eb;
--color-primary-foreground: #ffffff;
--color-secondary: #64748b;
// Uso en componentes
export function Hero() {
return (
<section className="container-narrow animate-fade-in py-18">
<h1 className="text-4xl font-bold text-primary">¡Hola!</h1>
<p className="mt-4 text-secondary">Construye algo genial.</p>
Lo que demuestra esto:
@import "tailwindcss" reemplaza las antiguas directivas @tailwind@theme para configuración CSS-first (sin archivo de configuración JS)@source para detección explícita de contenido@utility@varianttext-primary, shadow-soft, etc.)@import "tailwindcss" incluye todas las capas base, components y utilities de Tailwind@theme define propiedades personalizadas CSS que Tailwind convierte en clases de utilidad--color-* se convierte en text-*, bg-*, border-*; --spacing-* se convierte en p-*, m-*, gap-*@source indica a Tailwind dónde escanear nombres de clase (reemplaza content en la configuración de v3)@source solo es necesario para rutas no estándar@theme se compila a propiedades personalizadas CSS, lo que permite theming en tiempo de ejecuciónMigrar desde la configuración de v3:
# Herramienta de migración automática
npx @tailwindcss/upgrade/* colores de tailwind.config.js v3 → @theme v4 */
/* Antes (JS): colors: { brand: { 500: '#3b82f6' } } */
/* Después (CSS): */
@theme {
--color-brand-500: #3b82f6;
}Desactivar valores de tema por defecto:
@theme {
/* Elimina todos los colores por defecto */
--color-*: initial;
/* Define solo tus colores */
--color-primary: #2563eb;
--color-gray-50: #f9fafb;
--color-gray-900: #111827;
}Múltiples archivos CSS:
/* styles/theme.css */
@theme {
--color-brand: #3b82f6;
}
/* app/globals.css */
@import "tailwindcss";
@import "./styles/theme.css";// Sin impacto en TypeScript — Tailwind es solo CSS
// Pero puedes tipar tus tokens de tema para consistencia:
const themeColors = {
primary: "text-primary",
secondary: "text-secondary",
destructive: "text-destructive",
} as const;
type ThemeColor = keyof typeof themeColors;No hay tailwind.config.js por defecto — v4 no lee un archivo de configuración JS. Solución: Toda la configuración va en CSS vía @theme. Si debes usar configuración JS (para plugins), usa @config "./tailwind.config.js" en tu CSS.
@tailwind base/components/utilities se eliminó — v4 usa @import "tailwindcss" en su lugar. Solución: Reemplaza las tres directivas @tailwind con un solo @import.
El plugin de PostCSS cambió — El plugin ahora es @tailwindcss/postcss, no tailwindcss. Solución: Actualiza tu configuración de PostCSS.
Detección automática de contenido — v4 escanea tu proyecto automáticamente. Si las clases no se detectan, agrega rutas @source explícitas. Solución: Usa @source "../path/**/*.tsx" para ubicaciones de archivos no estándar.
Nombres de propiedades personalizadas CSS — Los valores de @theme deben seguir el patrón --category-name para generar utilidades correctas. --color-brand se convierte en text-brand, pero --brand-color no.
| Alternativa | Cuándo usarla | Cuándo no usarla |
|---|---|---|
| Tailwind v3 | Proyecto legacy que no está listo para migrar | Al iniciar un proyecto nuevo (v4 es más simple) |
| CSS Modules | Necesitas CSS con alcance local sin clases de utilidad | Quieres prototipado rápido con utilidades |
| Vanilla Extract | Quieres CSS-in-TS type-safe con cero runtime | Prefieres desarrollo utility-first |
| UnoCSS | Quieres un motor de utilidades ultrarrápido y configurable | Quieres el ecosistema y la comunidad de Tailwind |
@import "tailwindcss" reemplaza @tailwind base, @tailwind components y @tailwind utilities.
En tu archivo CSS dentro de bloques @theme { }. No hay tailwind.config.js por defecto.
--color-brand se convierte en text-brand, bg-brand, border-brand--spacing-18 se convierte en p-18, m-18, gap-18--font-family-sans se convierte en font-sansSolo cuando la detección automática de Tailwind no encuentra tus archivos. Agrega @source "../path/**/*.tsx" para ubicaciones de archivos no estándar.
Ejecuta npx @tailwindcss/upgrade. Convierte los valores de tu tailwind.config.js en bloques CSS @theme.
@theme {
--color-*: initial;
--color-primary: #2563eb;
}@tailwindcss/postcss, no tailwindcss. Usar el nombre antiguo fallará silenciosamente.
Los valores de tema deben seguir el patrón --category-name. --color-brand funciona, pero --brand-color no coincide con ninguna categoría de utilidad.
Pueden hacerlo. Usa @config "./tailwind.config.js" en CSS solo cuando necesites plugins basados en JS. Mueve todos los valores de tema a @theme para evitar conflictos.
const themeColors = {
primary: "text-primary",
secondary: "text-secondary",
} as const;
type ThemeColor = keyof typeof themeColors;Tailwind en sí es solo CSS, pero puedes crear un mapa de búsqueda tipado para consistencia.
@utility container-narrow {
max-width: 42rem;
margin-inline: auto;
}
@variant hocus (&:hover, &:focus-visible);Sí. Importa un archivo de tema separado después de @import "tailwindcss":
@import "tailwindcss";
@import "./styles/theme.css";