←

@theme inline en Tailwind v4: calc() con CSS variables para radii escalables

Contexto

El portfolio tiene dos temas con personalidades visuales diferentes: editorial (redondeado, 0.5rem) y terminal (afilado, 0.25rem). Necesitaba que rounded-sm, rounded-md, rounded-xl etc. escalaran proporcionalmente segun el tema activo.

Lo que aprendi

Tailwind v4 permite usar calc() con CSS variables dentro de @theme inline. Un solo token base (--radius) controla toda la escala de border-radius.

@theme inline {
  --radius-sm: calc(var(--radius) * 0.6);
  --radius-md: calc(var(--radius) * 0.8);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) * 1.4);
  --radius-2xl: calc(var(--radius) * 1.8);
  --radius-3xl: calc(var(--radius) * 2.2);
  --radius-4xl: calc(var(--radius) * 2.6);
}

Y en cada tema solo defines el valor base:

.theme-editorial { --radius: 0.5rem; }   /* redondeado */
.theme-terminal  { --radius: 0.25rem; }  /* afilado */

Resultado

UtilityEditorial (0.5rem base)Terminal (0.25rem base)
rounded-sm0.3rem0.15rem
rounded-md0.4rem0.2rem
rounded-lg0.5rem0.25rem
rounded-xl0.7rem0.35rem
rounded-2xl0.9rem0.45rem

Antes vs despues

Antes (7 valores hardcodeados por tema):

.theme-editorial { --radius-sm: 0.3rem; --radius-md: 0.4rem; /* ... */ }
.theme-terminal  { --radius-sm: 0.15rem; --radius-md: 0.2rem; /* ... */ }

Despues (1 valor por tema):

.theme-editorial { --radius: 0.5rem; }
.theme-terminal  { --radius: 0.25rem; }

7 lineas en @theme inline reemplazan 14 lineas de variables por tema. Y si agregas un tercer tema, solo defines --radius.

Por que @theme inline y no @theme

@theme inline permite referencing CSS variables (var(--radius)) y funciones como calc(). @theme (sin inline) espera valores literales resueltos en build time.

Referencia