Tipografía fluida en Tailwind
Los tamaños de texto por defecto de Tailwind son valores rem fijos — text-xl
es 1,25rem en cualquier viewport — y la tipografía fluida no viene incorporada.
Hay tres formas de añadirla: escribir expresiones clamp() en el bloque
@theme de la v4, poner un único clamp en el tamaño de fuente de la raíz para
que cada utilidad basada en rem fluya, o recurrir a un plugin de la comunidad.
Las dos primeras no necesitan ninguna dependencia, y la configuración CSS-first
de la v4 hizo la primera considerablemente más natural de lo que solía ser.
Este artículo calcula ambos caminos sin plugin con números reales. La aritmética que produce esos números — pendiente, intercepto, límites — se cubre en nuestra guía de tipografía fluida; la pregunta aquí es dónde viven los números en un proyecto Tailwind.
¿Por qué la tipografía fluida no viene incorporada en Tailwind?
La escala tipográfica de Tailwind es un conjunto de tokens con nombre,
estáticos: text-sm es 0,875rem, text-base es 1rem, text-xl es 1,25rem,
text-2xl es 1,5rem. El trabajo del framework es nombrar tamaños, no decidir
cómo responden al viewport — el comportamiento responsivo se expresa mediante
variantes como md:text-2xl, que es el modelo de breakpoints: tamaños que
saltan en anchos elegidos. Si en cambio quieres
tamaños que fluyen entre anchos,
tú aportas el flujo.
El cambio de la v4 es lo que hace barato aportarlo. La configuración se trasladó
a CSS: un token se declara en un
bloque @theme, se convierte en una
propiedad personalizada de CSS, y la utilidad correspondiente la lee — declara
--text-xl y text-xl usa tu valor. Como una propiedad personalizada puede
contener cualquier expresión de longitud de CSS, puede contener
un clamp(). Por tanto, la
tipografía fluida en la v4 es CSS corriente en un bloque corriente; en la v3, el
mismo movimiento significaba editar las entradas fontSize en
tailwind.config.js y pasar cadenas clamp a través de la configuración de
JavaScript.
¿Cómo se escriben tamaños de texto fluidos en @theme?
Redefine los tokens de texto. Aquí tienes tres tamaños en la forma fija que Tailwind trae por defecto:
@theme {
--text-base: 1rem; /* 16px en cualquier ancho */
--text-xl: 1.25rem; /* 20px en cualquier ancho */
--text-2xl: 1.5rem; /* 24px en cualquier ancho */
}
Y los mismos tres hechos fluidos — cada uno crece hasta 1,125× su tamaño a lo largo de viewports de 360→1280px:
@theme {
--text-base: clamp(1rem, 0.9511rem + 0.2174vw, 1.125rem); /* 16 → 18px */
--text-xl: clamp(1.25rem, 1.1889rem + 0.2717vw, 1.4063rem); /* 20 → 22.5px */
--text-2xl: clamp(1.5rem, 1.4266rem + 0.3261vw, 1.6875rem); /* 24 → 27px */
}
Comprueba --text-2xl en ambos extremos: en un viewport de 360px, 0.3261vw es
≈1,17px, y 22,83 + 1,17 ≈ 24px; en 1280px es ≈4,17px, y 22,83 + 4,17 ≈ 27px.
Escribir text-2xl en el marcado ahora renderiza 24px en un teléfono estrecho,
27px en un escritorio ancho, y el valor sobre la recta en todo punto intermedio
— sin variantes, sin media queries.
Dos detalles que vale la pena notar. Las pendientes difieren — 0,2174vw,
0,2717vw, 0,3261vw — pero cada una es proporcional al tamaño de su token, porque
cada token crece el mismo 12,5%. Esa proporción compartida es lo que mantiene la
jerarquía constante a lo largo del flujo; tres clamps calculados de forma
independiente, cada uno con una pendiente arbitraria, dejarían que los niveles
se separaran a medida que cambia el viewport. Y cada token de texto tiene un
token de interlineado acompañante (--text-xl--line-height), que conserva su
valor por defecto a menos que lo redefinas — el interlineado merece su propia
decisión una vez que los tamaños empiezan a moverse.
Calcular clamps proporcionales para toda una escala a mano es mecánico, que es
justo lo que lo hace generable: la exportación a Tailwind v4 de Scale Composer
en modo fluido escribe este bloque por ti. Define el flujo base (16→18 a lo
largo de 360→1280) y el clamp de cada nivel tipográfico se deriva de esa única
pendiente — abre la exportación de Tailwind en modo fluido y
activa el interruptor fijo/fluido para ver los valores del @theme alternar
entre rem corriente y las expresiones clamp() de arriba.

¿Puede un único clamp en la raíz hacer fluida cada utilidad?
El segundo camino no toca @theme en absoluto:
html {
font-size: clamp(1rem, 0.9511rem + 0.2174vw, 1.125rem); /* ≈16px @360 → ≈18px @1280 */
}
(Mantén los límites en rem: en el elemento raíz, rem se resuelve contra la preferencia de tamaño de fuente del navegador del lector, así que esta forma respeta ese ajuste — un clamp denominado en px lo anularía.)
Los tamaños de texto por defecto de Tailwind se basan en rem, y rem se resuelve
contra la raíz. Con la raíz fluyendo de 16px a 18px, text-xl renderiza 20px en
el extremo estrecho y 22,5px en el extremo ancho sin que cambie un solo token —
el tema por defecto intacto ya está listo para ser fluido. Dos líneas, y cada
utilidad que habla rem fluye.
Ese «cada» corta en ambos sentidos. Las utilidades de espaciado también se basan
en rem: p-4 es 1rem, que ahora renderiza 16px → 18px a lo largo del mismo
flujo. Para un sistema donde el espacio debe escalar con el texto — lo que
mantiene constantes las proporciones entre texto y espacio — eso es justo lo que
quieres. Pero es una decisión global: el flujo alcanza todo, y excluir un solo
componente significa escribir sus tamaños en px, saliendo del sistema de tokens
para ese elemento. El camino @theme es por token; el camino de la raíz es todo
o nada.
¿Qué añaden los plugins de tipografía fluida?
Una categoría de plugins de la comunidad genera clamps por tamaño a partir de la
configuración: declaras pares mín/máx, o una escala y un rango de viewport, y el
plugin emite utilidades fluidas — algunos añaden variaciones como el
dimensionamiento basado en container queries. Automatizan la misma aritmética
que este artículo hizo a mano, y son anteriores a la v4; parte de su valor
histórico era hacer en JavaScript lo que @theme ahora acepta como CSS
corriente. Si tus necesidades encajan en uno de los dos caminos de arriba, la v4
ha hecho opcional la dependencia; si quieres rangos por tamaño que no compartan
una sola proporción, un plugin puede llevar esa contabilidad — sopesado frente a
las habituales cuestiones de mantenimiento y compatibilidad que trae cualquier
dependencia.
¿Qué camino encaja con qué proyecto?
- El clamp en la raíz cuando todo el sistema — texto y espaciado — debe moverse como uno solo. Menos código, una sola pendiente que verificar, y la aritmética de accesibilidad y zoom se comprueba una vez, en la raíz.
- Los clamps de
@themecuando distintos niveles necesitan rangos distintos — un tamaño de display que crece más rápido que el texto de cuerpo, o un proyecto donde el espaciado debe permanecer fijo mientras el texto fluye. Más números, más control. - Un plugin cuando los rangos por tamaño se multiplican más allá de lo que quieres mantener a mano.
Los caminos también se combinan: varias configuraciones en producción aplican
clamp a la raíz para el flujo de todo el sistema y añaden uno o dos clamps de
@theme para los tamaños de display que necesitan un recorrido más pronunciado.
Genera el bloque a partir de tu propia escala
La forma más rápida de llegar a un bloque @theme fluido no es calcularlo sino
leerlo: abre la exportación con parámetros fluidos editables,
define tus propios tamaños base y rango de viewport, y observa cómo cada clamp
del bloque se recalcula a partir de los cuatro números. Pega el resultado en tu
hoja de estilos y las utilidades que ya escribes — text-xl, text-2xl —
empiezan a fluir.