Desarrollo web Intermedio

Tailwind CSS v4 desde cero (sin tailwind.config.js): configuración CSS-first con @theme y tokens listos para producción (Vite + React)

Olví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 …

Publicado: 28/12/2025 Por: Juan Felipe Orozco Cortés Duración: 20 minutos Nivel: Intermedio
Contenido del tutorial

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.

⚡ Vite 🌊 Tailwind CSS v4 🎨 @theme CSS-first 🌙 Dark Mode Manual 📘 TypeScript

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.

Nota de compatibilidad: Tailwind v4 apunta a navegadores modernos (Safari 16.4+, Chrome 111+, Firefox 128+). Si necesitas soporte legacy, mantente en v3.4.

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-variant para que el modo oscuro se active con una clase .dark en el HTML, y no solo por preferencia del sistema.
  • Tokens Semánticos: Variables como --color-surface o --color-ink que cambian de valor automáticamente según el tema, evitando llenar tu HTML de clases dark: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);
}

Estás viendo solo el 60% del contenido. Hazte Premium para acceder al tutorial completo.

Comunidad

Comentarios y valoraciones

No hay comentarios aún. ¡Sé el primero en opinar!