Menu

clamp() en CSS: tamaños de letra fluidos, min() y max()

clamp(MIN, PREFERIDO, MAX) devuelve el valor preferido, pero nunca menos que MIN ni más que MAX. Aprende cómo hace fluidos los tamaños de letra y los espaciados sin media queries, cómo calcular el valor del medio y cómo se relaciona con min() y max().

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Qué hace clamp()

clamp(MIN, PREFERRED, MAX) recibe tres valores y devuelve el del medio, siempre que se mantenga entre los otros dos. El uso clásico es un título que crece con la pantalla pero se detiene en límites razonables, sin media queries:

El valor preferido es 1rem + 3vw: 16px más el 3% del ancho. En una vista previa de 800px de ancho eso da 16 + 24 = 40px, que está entre 24px (1.5rem) y 48px (3rem), así que el título mide 40px. En un teléfono de 320px el valor preferido es 25.6px. Por encima de 1067px superaría los 48px, así que se detiene en 48px. Cambia el tamaño de la ventana para ver cómo cambia el número; aquí vw es un porcentaje del ancho del marco de la vista previa.

Míralo sin cambiar el tamaño de la ventana

vw sigue al viewport, que no es fácil cambiar mientras lees. Las unidades de container query siguen a un contenedor: cqi es el 1% del ancho del contenedor. Arrastra el control deslizante para cambiar la caja, y el mismo tipo de clamp() responde:

Deslízalo al principio y el título se detiene en 20px (el MIN). Deslízalo al final y se detiene en 40px (el MAX). En el medio sigue 0.5rem + 6cqi. Es el mismo mecanismo que la versión con vw, con una regla más pequeña.

Los tres argumentos

font-size: clamp(1rem, 0.8rem + 1vw, 1.5rem);
/*               MIN   PREFERRED     MAX    */
ArgumentoFunciónUnidad típica
MINlo más pequeño que puede llegar a ser el valorrem
PREFERREDel valor que cambia con la pantallarem + vw (o cqi)
MAXlo más grande que puede llegar a ser el valorrem

Dentro de cada argumento se pueden hacer cuentas sin escribir calc(): 1rem + 2vw está bien tal cual. El + y el - necesitan un espacio a cada lado, o toda la declaración es inválida.

Si MIN es mayor que MAX, gana MIN: clamp(3rem, 5vw, 2rem) siempre es 3rem.

Calcular el valor del medio

Para que una fuente crezca de 16px en una pantalla de 320px a 24px en una pantalla de 1280px:

  1. Pendiente: (24 − 16) ÷ (1280 − 320) = 8 ÷ 960 = 0.00833, que es 0.833vw (vw es por cada 100px).
  2. Punto de partida: 16px − 0.00833 × 320px = 13.33px, que es 0.833rem.
  3. Pon los límites alrededor:
font-size: clamp(1rem, 0.833rem + 0.833vw, 1.5rem);

Con 320px de ancho esto da 13.33 + 2.67 = 16px, con 1280px da 13.33 + 10.67 = 24px, y fuera de ese rango se queda en los límites. Las "calculadoras de clamp" en línea hacen exactamente esta cuenta.

min() y max()

clamp() es la combinación de dos funciones más simples:

  • min(a, b) devuelve el valor menor, así que define un límite superior.
  • max(a, b) devuelve el valor mayor, así que define un límite inferior.
  • clamp(MIN, VAL, MAX) es lo mismo que max(MIN, min(VAL, MAX)).

Los nombres parecen al revés al principio: para decir "como máximo 600px", usas min().

En la vista previa ancha, la primera tarjeta se detiene en 420px. Dentro del padre de 260px, 100% es el valor menor, así que la segunda tarjeta mide 260px. max(12px, 3%) le da a la primera tarjeta el 3% del ancho de su padre (el body: unos 23.5px en una vista previa de 800px), y a la segunda 12px, porque el 3% de 260px (7.8px) queda por debajo del mínimo.

width: min(100%, 420px) reemplaza en una sola declaración a la pareja antigua width: 100%; max-width: 420px;.

Más allá del tamaño de letra: espaciados y anchos

clamp() funciona en cualquier propiedad que acepte una longitud. Los porcentajes en el valor del medio hacen que un componente sea fluido respecto a su padre en lugar del viewport:

En el padre de 300px, la tarjeta mide 240px de ancho (80%) con 15px de padding (el 5% de 300px). En el padre de 760px, el 80% serían 608px, así que la tarjeta se detiene en su máximo de 520px, y el 5% de 760px son 38px, así que el padding se detiene en 32px.

Accesibilidad: mantén rem en el valor del medio

Un tamaño de letra hecho solo con vw, como font-size: 5vw, no crece cuando el lector sube el tamaño de letra por defecto en la configuración del navegador, y tampoco crece con el zoom del navegador, porque hacer zoom hace que el viewport sea más angosto en píxeles CSS. Agregar una parte en rem (1rem + 2vw) y límites en rem mantiene el texto ligado a la configuración del lector. La página de unidades explica rem y vw en detalle.

Errores comunes

  • Usar min() para un mínimo. min() elige el valor menor, que es un límite superior. Para "al menos 12px", usa max(12px, ...).
  • Sin espacios alrededor de + o -. clamp(1rem, 1rem+2vw, 3rem) es inválido, y la propiedad vuelve a su valor anterior.
  • Solo vw en el medio. El texto ignora entonces la configuración de tamaño de letra del lector. Agrega un término en rem.
  • MIN mayor que MAX. El resultado siempre es MIN, que rara vez es lo que se quería.
  • Límites en px para los tamaños de letra. Limitan el texto incluso para los lectores que lo necesitan más grande. Usa rem.

Preguntas frecuentes

¿Qué hace clamp() en CSS?

clamp(MIN, PREFERRED, MAX) usa el valor preferido mientras se mantiene entre los dos límites, y el límite más cercano en caso contrario. font-size: clamp(1rem, 4vw, 2rem) sigue el 4% del ancho del viewport, pero nunca baja de 1rem ni sube de 2rem.

¿Cómo hago un tamaño de letra responsive con clamp?

Pon un valor basado en el viewport en el medio y límites fijos a los lados, y mezcla rem en el medio para que el texto siga respetando la configuración de tamaño de letra del lector: font-size: clamp(1.5rem, 1rem + 2vw, 3rem);.

¿Qué pasa si el mínimo es mayor que el máximo en clamp()?

Gana el mínimo. clamp(3rem, 5vw, 2rem) siempre da 3rem, porque clamp() aplica el mínimo después del máximo.

¿Qué diferencia hay entre min() y max() en CSS?

min() devuelve el menor de sus valores, así que actúa como límite superior: width: min(100%, 600px) nunca es más ancho que 600px. max() devuelve el mayor, así que actúa como límite inferior: font-size: max(1rem, 2vw) nunca es menor que 1rem.

¿clamp() es compatible con todos los navegadores?

Sí, clamp(), min() y max() funcionan en todas las versiones actuales de Chrome, Edge, Firefox y Safari, y se pueden usar en cualquier propiedad que acepte una longitud, un número, un porcentaje o un ángulo.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR