Funciones CSS: calc, clamp, min, max

Domina las funciones matemáticas de CSS para crear valores dinámicos, tipografía fluida y layouts adaptativos sin media queries.

Las funciones matemáticas de CSS (calc, clamp, min, max) permiten calcular valores en tiempo real según el viewport, el contenedor o valores definidos. Son la base del responsive moderno sin media queries.


calc() — aritmética en CSS

calc() permite hacer operaciones matemáticas mezclando unidades distintas:

.sidebar {
  width: calc(300px - 2rem);              /* resta */
  height: calc(100vh - 80px);            /* viewport menos header */
  padding: calc(1rem + 5px);             /* suma de unidades distintas */
  font-size: calc(16px * 1.25);          /* multiplicación */
}

Reglas de sintaxis:

  • + y - necesitan espacios alrededor (calc(100% - 1rem), no calc(100%-1rem))
  • * y / no requieren espacios pero es buena práctica añadirlos
  • Al dividir, el divisor debe ser un número sin unidad
/* Columnas de igual tamaño con gap */
.col {
  width: calc((100% - (var(--columns) - 1) * var(--gap)) / var(--columns));
}

min() y max() — límites dinámicos

min() devuelve el valor más pequeño de los que recibe. max() devuelve el más grande:

/* min() — el valor más pequeño: nunca supera 500px pero es fluido antes */
.contenido {
  width: min(90%, 500px);
  /* si 90% del viewport < 500px → usa 90%; si no → usa 500px */
}

/* max() — el valor más grande: nunca baja de 300px */
.sidebar {
  width: max(300px, 25%);
  /* si 25% del viewport > 300px → usa 25%; si no → usa 300px */
}

Un patrón muy útil con min() para contenedores que ocupan todo el ancho en móvil pero se limitan en escritorio:

.container {
  width: min(100% - 2rem, 1200px);
  margin-inline: auto;
  /* En móvil: 100% - 2rem (margen de 1rem a cada lado)
     En escritorio: máximo 1200px centrado */
}

clamp() — valor entre un mínimo y un máximo

clamp(mínimo, ideal, máximo) es la función más poderosa para valores fluidos. Devuelve el valor ideal siempre que esté entre el mínimo y el máximo:

clamp(mínimo, valor-ideal, máximo)
.titulo {
  font-size: clamp(1.5rem, 4vw, 3rem);
  /*                ^         ^      ^
                mínimo   fluido  máximo
     En pantallas pequeñas: nunca menos de 1.5rem
     En pantallas intermedias: 4% del ancho del viewport
     En pantallas grandes: nunca más de 3rem */
}

clamp() reemplaza este patrón con media queries:

/* Sin clamp — necesita media queries */
.titulo { font-size: 1.5rem; }
@media (min-width: 600px) { .titulo { font-size: 2rem; } }
@media (min-width: 1200px) { .titulo { font-size: 3rem; } }

/* Con clamp — un valor fluido sin media queries */
.titulo { font-size: clamp(1.5rem, 2vw + 1rem, 3rem); }

Tipografía fluida con clamp

El patrón 2vw + 1rem en el valor ideal de clamp es una fórmula que escala suavemente: la parte 1rem fija el tamaño base y 2vw lo añade proporcionalmente al ancho del viewport:

:root {
  /* Escala tipográfica fluida */
  --text-sm:   clamp(0.8rem,  0.5vw + 0.6rem, 0.9rem);
  --text-base: clamp(1rem,    0.5vw + 0.8rem, 1.125rem);
  --text-lg:   clamp(1.125rem, 1vw + 0.75rem, 1.5rem);
  --text-xl:   clamp(1.5rem,  2vw + 0.75rem, 2.25rem);
  --text-2xl:  clamp(2rem,    3vw + 0.75rem, 3.5rem);
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
p  { font-size: var(--text-base); }

Con esto la tipografía escala suavemente entre móvil y escritorio sin ninguna media query.


Espaciado fluido

El mismo principio aplicado al espaciado:

:root {
  --space-s:  clamp(0.75rem, 2vw, 1rem);
  --space-m:  clamp(1rem,    4vw, 2rem);
  --space-l:  clamp(2rem,    6vw, 4rem);
  --space-xl: clamp(4rem,    8vw, 8rem);
}

section {
  padding-block: var(--space-xl);  /* más espacio en escritorio, menos en móvil */
}

Combinando funciones

Las funciones se pueden anidar:

/* clamp con calc en el valor ideal */
font-size: clamp(1rem, calc(1rem + 1vw), 2rem);

/* min y max juntos */
width: min(max(300px, 50%), 800px);
/* igual a clamp(300px, 50%, 800px) */

/* El gap de un grid fluido */
.grid {
  gap: clamp(1rem, 3vw, 2.5rem);
}

Funciones de transformación en calc

/* Centrado vertical clásico */
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Alternativa moderna: */
  /* top: calc(50% - 150px); — si conoces la altura exacta */
}

/* Altura completa menos elementos fijos */
.main-content {
  min-height: calc(100dvh - var(--header-height) - var(--footer-height));
}

100dvh (dynamic viewport height) es la alternativa moderna a 100vh que tiene en cuenta la barra de navegación en móviles, que a veces aparece y desaparece cambiando la altura útil.


En la siguiente lección volvemos a Grid pero más profundo: áreas nombradas, auto-fill/auto-fit, minmax() y subgrid para layouts complejos que antes eran casi imposibles.