Qué hace calc()
calc() hace aritmética dentro de un valor CSS, y puede mezclar unidades que solo tienen tamaño al hacer el layout. El caso clásico es "todo el ancho menos una barra lateral fija":
100% solo se conoce cuando la página ya se acomodó, y 180px es fijo, así que ninguna unidad por sí sola podría expresarlo. calc() lo resuelve: en una vista previa de 800px de ancho, la fila mide 784px y la columna principal recibe 604px, y la línea debajo del layout imprime los números reales. Hoy flexbox o grid harían este layout sin cuentas, pero la misma resta sigue apareciendo en todas partes: una altura menos un encabezado, un ancho menos un gap.
Las reglas de sintaxis
width: calc(100% - 2rem); /* + and - need spaces on both sides */
width: calc(100% / 3); /* divide by a plain number */
margin: calc(var(--space) * 2); /* multiply by a plain number */
height: calc(100vh - (64px + 1rem)); /* parentheses group */
| Regla | Válido | Inválido |
|---|---|---|
Espacios alrededor de + y - | calc(100% - 20px) | calc(100%-20px) |
*: al menos un lado es un número simple | calc(2 * 1rem) | calc(2px * 3px) |
/: divide una longitud entre un número simple | calc(100% / 3) | width: calc(300px / 3px) (no es una longitud) |
| Las unidades deben ser compatibles | calc(1rem + 10px) | calc(1rem + 2s) |
La regla de los espacios existe porque 100% -20px se leería como dos valores separados, el segundo un número negativo. Cuando un calc() es inválido, se descarta toda la declaración y el elemento conserva el valor que tenía de reglas anteriores.
Prueba una expresión
Escribe cualquier expresión para el ancho de la caja. El navegador informa si es válida y el ancho que calculó:
Prueba 100%-200px (inválido, sin espacios), 100% / 3, 50% + 4rem, 2 * 120px, 200px * 2px (inválido) y (100% - 40px) / 2.
calc() con variables CSS
Las variables y calc() van juntas: guarda un valor base una vez y deriva el resto de él. Una variable sin unidad se convierte en una longitud cuando la multiplicas por una unidad:
Cambia --space a 12px o --cols a 4 y todos los valores derivados lo siguen. La página de variables CSS explica cómo declararlas y su alcance.
Usos habituales
| Necesidad | calc() |
|---|---|
| Llenar el espacio junto a un elemento fijo | width: calc(100% - 240px) |
| Sección debajo de un encabezado fijo | min-height: calc(100vh - 64px) |
| La mitad del ancho menos medio gap | width: calc(50% - 8px) |
| Centrar una caja de 100px con posición absoluta | left: calc(50% - 50px) |
| Tamaño de letra que crece un poco con la pantalla | font-size: calc(1rem + 0.5vw) |
| Convertir una variable numérica en longitud | calc(var(--n) * 1px) |
| El negativo de una variable | calc(var(--space) * -1) |
Para un valor que debe mantenerse entre límites, usa clamp(), que acepta las mismas cuentas en sus argumentos sin escribir calc().
Dónde funciona calc()
En cualquier lugar donde se permita una longitud, un porcentaje, un número, un ángulo o un tiempo: width, margin, padding, top, font-size, line-height, los tamaños de las pistas de grid, transition-delay y los ángulos dentro de transform. Se puede anidar, y un calc() anidado es lo mismo que unos paréntesis simples.
Los ángulos son un buen ejemplo. Cada marca de abajo tiene su propio --i (de 0 a 11), y una sola regla lo convierte en un ángulo con calc(var(--i) * 30deg):
La marca 3 recibe rotate(90deg), que Chrome informa como la matriz matrix(0, 1, -1, 0, 0, 0): un cuarto de vuelta. left: calc(50% - 2px) centra cada marca restando la mitad de su propio ancho de 4px.
Errores comunes
- Sin espacios alrededor de
-o+.calc(100%-20px)es inválido y se ignora. - Multiplicar dos longitudes.
calc(10px * 2px)no tiene significado en CSS. Un lado de*debe ser un número simple. - Usar calc() para una altura en porcentaje sin altura en el padre.
calc(100% - 20px)enheightnecesita un padre con una altura definida, igual queheight: 100%. - Usar calc() donde bastaría flexbox o grid.
width: calc(33.333% - 10px)para columnas es frágil;display: grid; grid-template-columns: repeat(3, 1fr); gap: 15pxno necesita cuentas. - Esperar un mensaje de error. El navegador no avisa de un calc() inválido. Revisa el elemento en las herramientas para desarrolladores: una declaración inválida aparece tachada.
Preguntas frecuentes
¿Qué hace calc() en CSS?
Calcula un valor a partir de una expresión con +, -, * y /, y puede mezclar unidades que el navegador solo conoce al hacer el layout. width: calc(100% - 200px) es el ancho completo del padre menos 200px, sea cual sea el ancho del padre.
¿Por qué no funciona mi calc()?
La causa más común es que faltan espacios: + y - deben tener espacio en blanco a los dos lados, así que calc(100%-20px) es inválido. Otras causas son multiplicar dos longitudes (10px * 2px) o dividir por una longitud, que no da una longitud. Un calc() inválido hace que toda la declaración sea inválida, así que el navegador la ignora.
¿Puedo usar variables CSS en calc()?
Sí. calc(var(--gap) * 2) duplica una variable, y calc(var(--columns) * 1px) convierte un número sin unidad en píxeles. Primero se sustituye el valor de la variable y después se hace la cuenta.
¿Necesito espacios alrededor de * y / en calc()?
No. Solo + y - exigen espacios, porque sin ellos -20px se leería como un número negativo. Los espacios alrededor de * y / son opcionales, pero escribirlos siempre es la regla más fácil de recordar.
¿Qué diferencia hay entre calc() y clamp()?
calc() calcula un valor a partir de una expresión. clamp(MIN, VAL, MAX) mantiene un valor entre dos límites. Se combinan: cada argumento de clamp() ya puede contener cuentas al estilo de calc, como clamp(1rem, 1rem + 2vw, 3rem).