Mueve un control de ancho del viewport y mira cómo calc(), min(), max() y clamp() se resuelven en píxeles. Además, vh frente a svh, lvh y dvh, fit-content y min-content en vivo, gap y recetas de tipografía fluida.
Las funciones matemáticas de CSS permiten que un valor se adapte a la pantalla. calc() mezcla unidades, como en calc(100% - 2rem). min() elige la opción más pequeña, así que width: min(100%, 640px) nunca desborda. max() elige la más grande, y clamp(min, preferred, max) mantiene un valor fluido entre dos límites. dvh sigue la barra de herramientas cambiante del navegador móvil, a diferencia de vh.
Qué función para cada tarea
Tarea
CSS
Ancho completo menos un margen fijo
width: calc(100% - 2rem)
Una columna con tope en 640px
width: min(100%, 640px)
Padding que nunca baja de 1rem
padding: max(1rem, 4vw)
Encabezado que escala entre 2rem y 3.5rem
font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem)
Hero que llena la pantalla móvil visible
min-height: 100dvh
En lugar de redimensionar el navegador para probar una fórmula, arrastra el ancho de viewport simulado y cada función se resuelve en píxeles delante de ti, con el punto donde clamp() alcanza sus límites marcado. La página también dibuja lo que miden vh, svh, lvh y dvh en un teléfono y muestra las palabras clave intrínsecas funcionando en cajas reales.
Arrastra el control de ancho del viewport desde tamaño de teléfono hasta un monitor ancho.
Ajusta los valores mínimo, preferido y máximo de la fórmula clamp() y observa su resultado en píxeles.
Compara las filas de min(), max() y calc() resolviéndose al mismo ancho.
Copia la fórmula y después prueba las cajas de tamaño por contenido y los ejemplos de gap de abajo.
Los espacios alrededor de + y - dentro de calc() son obligatorios. calc(100%-2rem) no es válido; calc(100% - 2rem) funciona.
Mantén un término en rem en el medio de un clamp() de fuente fluida, para que el texto siga respondiendo cuando el lector hace zoom o cambia el tamaño por defecto.
min() y max() parecen al revés al principio: min() fija un tamaño máximo, porque siempre toma el valor más pequeño.
Usa dvh con moderación en secciones a pantalla completa, porque su valor cambia cuando se mueve la barra y puede desplazar el contenido al hacer scroll. svh es la opción estable.
Preguntas frecuentes
¿Qué diferencia hay entre vh, svh, lvh y dvh?
En los teléfonos, la barra de herramientas del navegador crece y se encoge. svh es el 1% del viewport pequeño, con la barra visible. lvh es el 1% del viewport grande, con la barra oculta. dvh sigue el que esté activo y se actualiza al hacer scroll. El vh clásico suele ser igual a lvh, por eso las secciones de 100vh se cortan en móvil.
¿clamp(), min() y max() funcionan en todas partes?
Sí, las tres funcionan en todos los navegadores principales desde 2020. Las unidades de viewport pequeño, grande y dinámico llegaron más tarde, durante 2022, y ya están en todos los navegadores principales actuales. Añade antes una línea de reserva con vh si todavía das soporte a dispositivos antiguos.
¿Cómo escribo un tamaño de fuente fluido con clamp()?
Elige el tamaño en una pantalla estrecha y en una ancha, y escribe clamp(pequeño, preferido, grande). El valor preferido combina rem y vw, como 1rem + 2vw, así que el tamaño crece con la ventana pero se queda entre los dos límites. El laboratorio de abajo muestra los anchos exactos en los que entran en juego los límites.
¿Qué hace fit-content?
width: fit-content ajusta una caja a su contenido, como un inline-block encogido, pero nunca más ancha que el espacio disponible. Equivale a min(max-content, max(min-content, espacio disponible)). La función fit-content() en las pistas de grid hace lo mismo con un límite que eliges tú.
¿Se puede usar gap con flexbox?
Sí. gap, row-gap y column-gap funcionan en contenedores flex en todos los navegadores actuales, no solo en grid. El gap se añade solo entre elementos, nunca en los bordes exteriores, lo que es más sencillo que poner márgenes en cada hijo.
Cómo se resuelve calc()
calc() espera al momento del layout para resolverse, así que puede combinar un porcentaje que depende del padre con un valor en rem o píxeles. Puedes anidar calc() dentro de min(), max() y clamp() y usar custom properties dentro, como calc(var(--gutter) * 2).
La multiplicación y la división necesitan al menos un número sin unidad: calc(2 * 1rem) está bien, calc(1rem * 1rem) no. Dividir entre cero invalida la declaración.
Tamaños intrínsecos: min-content, max-content y fit-content
min-content es lo más estrecha que puede ser una caja sin desbordar, normalmente el ancho de su palabra más larga o de su imagen más ancha. max-content es el ancho que ocuparía si el texto nunca saltara de línea. Ambos son útiles para pistas de grid y para etiquetas que deben ajustarse a su texto.
fit-content queda entre los dos: es tan ancha como quiere el contenido, pero salta de línea cuando el contenedor es más estrecho. Eso la convierte en una forma limpia de centrar una caja ajustada con margin-inline: auto.
Espaciado fluido además de tipografía fluida
El mismo truco de clamp() funciona para padding, márgenes y gaps. Una sección con padding-block: clamp(2rem, 6vw, 6rem) respira en pantallas grandes sin desperdiciar espacio en un teléfono.
Define los valores fluidos una sola vez como custom properties, por ejemplo --space-m y --step-2, y úsalos en todas partes. Cambiar la escala más adelante supone editar una línea en lugar de rebuscar entre componentes.
vh frente a svh, lvh y dvh
Unidades de porcentaje del viewport
Unidad
1 unidad equivale a
¿Cambia al hacer scroll?
Úsala para
vh / vw
1% del viewport (en móvil, normalmente el grande)
No
Layouts de escritorio, reserva para navegadores antiguos
svh / svw
1% del viewport pequeño, con barras visibles
No
Secciones a pantalla completa que nunca deben quedar ocultas
lvh / lvw
1% del viewport grande, con barras ocultas
No
Fondos que deben cubrirlo todo
dvh / dvw
1% del viewport actual
Sí
Layouts que deben seguir a la barra de herramientas
vmin / vmax
1% del lado menor o mayor
No
Elementos cuadrados que encajen en cualquier orientación
cqi / cqw
1% del tamaño inline de un contenedor de tamaño
Con el contenedor
Componentes dentro de container queries
Un hero de altura completa seguro en móvil
La primera línea es la reserva para navegadores sin las unidades nuevas. La segunda la sustituye donde hay soporte.
Ejemplos de calc(), min(), max() y clamp()
Una columna legible sin media query
min() limita el ancho; el padding usa max() para que nunca baje de 12px. Ambas reglas se adaptan solas al ancho del marco.
calc() para una barra lateral fija junto a un área principal fluida
El área principal ocupa lo que queda tras la barra lateral de 120px y el gap de 12px.
min-content, max-content y fit-content
Palabras clave de tamaño intrínseco
Palabra clave
El ancho pasa a ser
Tailwind
La palabra indivisible más larga o la imagen más ancha
Todo el contenido en una línea, aunque desborde
max-content, pero nunca más ancho que el espacio disponible
fit-content(300px) en grid
Como fit-content con un tope de 300px
grid-cols-[fit-content(300px)_1fr]
gap en flex y grid
El mismo gap en una fila flex con salto de línea y en un grid
row-gap y column-gap pueden ser distintos. Ninguno añade espacio en los bordes exteriores.
Escala fluida de tipografía y espaciado
Una pequeña escala fluida como custom properties
Cada paso crece aproximadamente entre un teléfono de 360px y un escritorio de 1280px. Ajusta los números en el laboratorio de arriba.
Laboratorio de viewport
Ancho de viewport simulado (px)
Encabezado fluido a {px}px
Valores resueltos al ancho simulado
Función
Declaración
A {vp}px
mínimo de clamp (rem)
máximo de clamp (rem)
preferido: parte en rem
preferido: parte en vw
El máximo es menor que el mínimo, así que el mínimo gana en todos los anchos.
Se queda en {min}rem hasta unos {from}px de ancho, crece hasta unos {to}px y luego se mantiene en {max}rem.
Sin parte en vw, el valor nunca cambia con la ventana.
Copiar
Lo que cubren 100 unidades de cada tipo en un teléfono
Tres teléfonos: 100svh llena el espacio entre las barras visibles, 100lvh llena toda la pantalla como si las barras estuvieran ocultas, 100dvh sigue a las barras cuando cambian
barras visibles
barras ocultas
sigue a las barras
Las franjas grises son las barras del navegador. El azul es el área que llenan 100 unidades.
Tamaño por contenido, en vivo
Palabra clave de ancho
Espacio disponible (px)
Envío gratis en todos los pedidos este fin de semana