Tailwind CSS v4 desde cero (sin tailwind.config.js): configuración CSS-first con @theme y tokens listos para producción (Vite + React)
Inicia sesión para descargarOlvídate del tailwind.config.js. En este tutorial aprenderás la nueva arquitectura "CSS-first" de Tailwind CSS v4. Configuraremos el plugin oficial para Vite, definiremos un sistema de diseño (colores, sombras, tipografía) usando el bloque …
Domina Tailwind CSS v4 en Producción
Si estás cansado de configurar postcss.config.js y quieres ver el futuro del CSS, este tutorial es para ti.
Vamos a montar un setup moderno con Tailwind v4 + Vite que incluye un sistema de tokens semánticos (colores, sombras, radios) usando el nuevo @theme nativo de CSS y un modo oscuro manual robusto.
Al finalizar este tutorial tendrás una arquitectura "CSS-first". Olvídate de archivos de configuración JS gigantes; en v4, tus tokens viven en CSS y generan utilidades automáticamente.
1. Crear el proyecto e Instalar Dependencias
Empezamos con lo básico: un proyecto Vite con React y TypeScript limpio. No uses plantillas viejas, vamos a configurarlo desde cero.
# 1. Crear el proyecto
npm create vite@latest tucodigo-tailwind-v4 -- --template react-tscd tucodigo-tailwind-v4
cd tucodigo-tailwind-v4
npm install
# 2. Instalar Tailwind v4 (y su plugin oficial para Vite)
npm install tailwindcss @tailwindcss/vite
2. Activar el plugin en vite.config.ts
En la versión 4, Tailwind ya no depende de PostCSS para integrarse con Vite. Ahora tenemos un plugin dedicado que es mucho más rápido y gestiona las dependencias automáticamente.
Abre tu archivo vite.config.ts y asegúrate de importar y ejecutar tailwindcss() dentro de los plugins:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [react(), tailwindcss()],
});
3. Tokens de Producción con @theme (La magia de v4)
Aquí es donde todo cambia. En lugar de un objeto JSON en tailwind.config.js, definimos nuestras variables directamente en CSS dentro de un bloque @theme.
Vamos a configurar:
- Dark Mode Manual: Usaremos
@custom-variantpara que el modo oscuro se active con una clase.darken el HTML, y no solo por preferencia del sistema. - Tokens Semánticos: Variables como
--color-surfaceo--color-inkque cambian de valor automáticamente según el tema, evitando llenar tu HTML de clasesdark:bg-slate-900.
Reemplaza todo el contenido de src/index.css con esto:
@import "tailwindcss";
/* Dark mode manual (en vez de prefers-color-scheme).
Activa dark:* cuando exista .dark en el árbol HTML */
@custom-variant dark (&:where(.dark, .dark *));
/* docs: puedes usar clase o data-attribute */
@theme {
/* =========================
1) PALETA (brand)
========================= */
--color-brand-50: oklch(0.97 0.02 250);
--color-brand-100: oklch(0.93 0.04 250);
--color-brand-200: oklch(0.88 0.06 250);
--color-brand-300: oklch(0.82 0.08 250);
--color-brand-400: oklch(0.74 0.10 250);
--color-brand-500: oklch(0.66 0.12 250);
--color-brand-600: oklch(0.58 0.14 250);
--color-brand-700: oklch(0.50 0.14 250);
--color-brand-800: oklch(0.42 0.12 250);
--color-brand-900: oklch(0.34 0.10 250);
/* =========================
2) TOKENS SEMÁNTICOS (light por defecto)
- Ventaja: usas bg-surface, text-ink, border-line
y cambias el “skin” solo con variables
========================= */
--color-surface: oklch(1 0 0);
--color-surface-2: oklch(0.98 0.01 250);
--color-ink: oklch(0.20 0.02 250);
--color-muted: oklch(0.50 0.02 250);
--color-line: oklch(0.90 0.02 250);
/* =========================
3) TIPOGRAFÍA
========================= */
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
/* =========================
4) RADIUS + SHADOW (component feel “pro”)
========================= */
--radius-card: 1rem;
--shadow-card: 0 12px 30px rgb(0 0 0 / 0.08);
/* =========================
5) BREAKPOINT extra (ej: xs:)
========================= */
--breakpoint-xs: 30rem; /* ahora existe xs:* */
}
/* =========================
DARK THEME (solo cambiamos variables)
- esto funciona porque las utilidades usan var(--color-*)
========================= */
.dark {
--color-surface: oklch(0.17 0.02 250);
--color-surface-2: oklch(0.22 0.02 250);
--color-ink: oklch(0.96 0.01 250);
--color-muted: oklch(0.78 0.02 250);
--color-line: oklch(0.30 0.02 250);
}
Comentarios y valoraciones
No hay comentarios aún. ¡Sé el primero en opinar!