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 */
| Argumento | Función | Unidad típica |
|---|---|---|
| MIN | lo más pequeño que puede llegar a ser el valor | rem |
| PREFERRED | el valor que cambia con la pantalla | rem + vw (o cqi) |
| MAX | lo más grande que puede llegar a ser el valor | rem |
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:
- Pendiente: (24 − 16) ÷ (1280 − 320) = 8 ÷ 960 = 0.00833, que es 0.833vw (vw es por cada 100px).
- Punto de partida: 16px − 0.00833 × 320px = 13.33px, que es 0.833rem.
- 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 quemax(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", usamax(12px, ...). - Sin espacios alrededor de
+o-.clamp(1rem, 1rem+2vw, 3rem)es inválido, y la propiedad vuelve a su valor anterior. - Solo
vwen el medio. El texto ignora entonces la configuración de tamaño de letra del lector. Agrega un término enrem. - MIN mayor que MAX. El resultado siempre es MIN, que rara vez es lo que se quería.
- Límites en
pxpara los tamaños de letra. Limitan el texto incluso para los lectores que lo necesitan más grande. Usarem.
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.