Saltar al contenido

CSS, de a poco

Curso de CSS

Funciones de tamaño

Lección 19 de 37 · 4 min

Con unidades fijas, un tamaño vale lo mismo en un teléfono y en un monitor. Las funciones de CSS hacen la cuenta en el navegador, así que un mismo valor se adapta solo al lugar que hay.

calc(), min() y max()

calc() hace cuentas mezclando unidades, algo que no podés resolver de antemano: calc(100% - 2rem) es todo el ancho menos 32px, sea cual sea ese ancho. El + y el - necesitan un espacio a cada lado; sin ellos, 100%-2rem se lee como un número negativo pegado y el navegador descarta la declaración. El * y la / no los necesitan.

min() devuelve el menor de sus valores y max() el mayor. En la práctica funcionan como techo y piso: min(100%, 30rem) nunca pasa de 30rem, y max(1rem, 5vw) nunca baja de 1rem. Adentro aceptan cuentas sin escribir calc().

caja.css
.caja {
width: calc(100% - 2rem); /* todo el ancho menos 32px */
width: min(100%, 30rem); /* el 100%, pero nunca más de 480px */
padding-inline: max(1rem, 5vw); /* el 5vw, pero nunca menos de 16px */
}

Mové el ancho del viewport y mirá qué valor gana en cada función. El título usa clamp(), que combina las dos; subí el mínimo para verlo ganar en pantallas chicas.

font-size: clamp(1rem, 0.75rem + 1.5vw, 2rem)Con 800px de viewport: relleno 40px, columna 480px, título 24px (gana el preferido)
padding-inline
max(1rem, 5vw)
40px
width
min(100%, 30rem)
480px
font-size
clamp(1rem, 0.75rem + 1.5vw, 2rem)
24px
pagina.css
.pagina {
padding-inline: max(1rem, 5vw); /* = 40px */
}
.articulo {
width: min(100%, 30rem); /* = 480px */
margin-inline: auto;
}
.titulo {
font-size: clamp(1rem, 0.75rem + 1.5vw, 2rem); /* = 24px */
}
pagina.html
<main class="px-[max(1rem,5vw)]">
<article class="mx-auto w-[min(100%,30rem)]">
<h1 class="text-[clamp(1rem,0.75rem+1.5vw,2rem)]">Una semana en Banff</h1>
</article>
</main>

clamp() y tipografía fluida

clamp(mínimo, preferido, máximo) devuelve el valor preferido mientras quede entre los dos límites. Es lo mismo que max(mínimo, min(preferido, máximo)), así que si el mínimo es mayor que el máximo, gana el mínimo.

Para tipografía fluida, el preferido crece con el viewport. Armalo como rem + vw y no solo con vw: el zoom no cambia cuánto mide 1vw en la pantalla, así que un título en 5vw no se agranda y puede fallar el criterio 1.4.4 de WCAG, que pide poder ampliar el texto al 200%. La parte en rem sí sigue al zoom y al tamaño de letra que elige quien lee. Igual probalo: si el vw pesa mucho, puede no llegar al doble.

Para sacar los números, partí de dos puntos: 18px en un viewport de 320px y 36px en uno de 1280px.

  1. Pendiente1.875vw(36 - 18) / (1280 - 320) = 0.01875. Por 100 da 1.875vw.
  2. Ordenada al origen0.75rem18 - 0.01875 × 320 = 12px, o sea 0.75rem.
  3. Límites1.125rem · 2.25rem18px y 36px, pasados a rem.
Gráfico del font-size según el ancho del viewport: 18px fijos hasta 320px, una recta que sube de 18 a 36px entre 320 y 1280px, y 36px fijos de ahí en adelante.
titulo.css
h1 {
/* 18px con 320px de viewport, 36px con 1280px */
font-size: clamp(1.125rem, 0.75rem + 1.875vw, 2.25rem);
}

Más allá del texto

Las mismas funciones sirven para cualquier longitud:

  1. Rellenopadding-inline: max(1rem, 5vw)Deja 16px en un teléfono y el 5% del viewport a partir de 320px de ancho.
  2. Ancho de lecturawidth: min(100%, 40rem)Ocupa todo en pantallas chicas y se frena en 640px, sin un max-width aparte.
  3. Componentesclamp(1rem, 0.5rem + 4cqi, 1.5rem)Con cqi en vez de vw sigue al ancho del contenedor y no al de la pantalla. Lo vimos en container queries.

También existen round(), que redondea a un múltiplo (round(nearest, 37px, 8px) da 40px), y mod(), que devuelve el resto de una división. Son recientes: funcionan en todos los navegadores principales recién desde 2024, así que poné antes una declaración sin la función como respaldo.

En Tailwind

Tailwind no tiene utilidades para estas funciones: van como valores arbitrarios, entre corchetes. Una clase no puede tener espacios, así que se escriben sin ellos y Tailwind los vuelve a poner alrededor del + y el - al compilar.

CSSTailwind
font-size: clamp(1rem, 0.75rem + 1.5vw, 2rem)text-[clamp(1rem,0.75rem+1.5vw,2rem)]
width: min(100%, 30rem)w-[min(100%,30rem)]
padding-inline: max(1rem, 5vw)px-[max(1rem,5vw)]
width: calc(100% - 2rem)w-[calc(100%-2rem)]
pagina.html
<!-- relleno fluido y una columna de lectura centrada -->
<main class="px-[max(1rem,5vw)]">
<article class="mx-auto w-[min(100%,40rem)]">
<h1 class="text-[clamp(1.125rem,0.75rem+1.875vw,2.25rem)]">…</h1>
</article>
</main>
<!-- un título que sigue a su contenedor -->
<div class="@container">
<h2 class="text-[clamp(1rem,0.5rem+4cqi,1.5rem)]">…</h2>
</div>