A lo largo de mi experiencia trabajando con CSS, uno de los problemas más grandes que he tenido o he visto, son las medidas 📏 (porcentajes, píxeles, medidas relativas, etc.), pues siempre tengo problemas de que por ciertas circunstancias o situaciones el contenido no se ve bien o tengo que hacer algunos cambios para que se vea acorde a lo que necesito, porque seamos honestos, a pesar de que CSS es amor ❤️ a veces suele ser un gran dolor.

Yo intentando ser romántico 😁

CSS

calc() al rescate

Ver soporte

Con calc() podemos realizar cálculos y así determinar distintos valores en las propiedades CSS, para realizar los cálculos tenemos cuatro operadores matemáticos:

  • ➕ Suma (+)
  • ➖ Resta (-)
  • ✖️ Multiplicación (*)
  • ➗ División (/)

Sintaxis

La sintaxis de calc() no es nada del otro mundo, es simplemente una propiedad extra, que agregamos a nuestro CSS.

elemento {  
    width: calc(expresión);
}

calc() no solo funciona con width, lo podemos usar en todas las propiedades que requieran de medidas, como height, background-position, line-height, etc.

Usando calc()

Bien llego el momento en el cual vamos a poner en práctica ✏️ calc() y algunos ejemplos de su uso.

Viendo los distintos operadores

Para empezar todo esto de una manera sencilla, quiero poner como ejemplo los cuatro operadores que podemos usar y que es lo que pasa, dependiendo del operador .

HTML

<div class="elemento-1"></div>  
<div class="elemento-2"></div>  
<div class="elemento-3"></div>  
<div class="elemento-4"></div>  

CSS

div {  
  background-color: #FFE066;
  height: 100px;
  margin: 0.5rem 0;
}

.elemento-1 {
  width: calc(20% + 20px); /* El ancho va a ser de 20%, más 20px adicionales */
}

.elemento-2 {
  width: calc(20% - 20px) /* El ancho va a ser de 20%, menos 20px adicionales */
}

.elemento-3 {
  width: calc(20% * 2) /* El ancho va a ser de 40% */
}

.elemento-4 {
  width: calc(20% / 2) /* El ancho va a ser de 10% */
}

Como puedes ver en el código, tenemos cuatro elementos con un color de fondo, alto y margen totalmente igual, pero el ancho se comporta de diferente forma (dependiendo de su operador).

Medidas relativas y calc()

Las medidas relativas no están al 100% definidas, ya que su valor depende de otro valor, por ejemplo em depende del tamaño de letra de su padre 👨🏻.

HTML

<div class="padre">  
  <div class="hijo">Hola</div>
</div>  

CSS

.padre {
    font-size: 16px;
}

/* CASO 1: */
.hijo {
    font-size: 1em; /* El hijo va a tener un tamaño de fuente de 16px */
}

/* CASO 2: */
.hijo {
    font-size: 1.5em; /* El hijo va a tener un tamaño de fuente de 24px */
}

/* CASO 3: */
.hijo {
    font-size: 0.5em; /* El hijo va a tener un tamaño de fuente de 8px */
}

Como puedes ver, el tamaño de fuente del hijo 👶🏻 va a cambiar, dependiendo del tamaño de fuente del padre, si el padre cambia su tamaño de fuente a font-size: 32px; y él hijo a font-size: 1em;, el resultado del hijo va a ser de 32px.

Sé que todo esto de medidas relativas puede ser algo complejo en un principio, pero es más fácil de lo que parece. Si quieres saber más de este tema, te recomiendo el artículo de Unidades de medidas en CSS que esta en el blog 🖥 de Platzi.

Ahora bien, doy por hecho que ya sabes de medidas relativas en CSS, ahora vamos a usarlo junto con calc().

HTML

<div class="padre">  
  <div class="hijo-1"></div>
  <div class="hijo-2"></div>
  <div class="hijo-3"></div>
</div>  

CSS

.padre {
  width: 200px;
  height: 200px;
  background-color: #50514F;
  font-weight: 16px;
}

.padre div {
  height: 50px;
  margin: 0.5rem 0;
  background-color: #299FD3;
}

.padre .hijo-1 {
  width: calc(100% - 1em) /* 100%, menos 16px */
}

.padre .hijo-2 {
  width: calc(100% - 5em) /* 100%, menos 80px */
}

.padre .hijo-3 {
  width: calc(100% + 8em) /* 100%, más 128px */
}

En el código tenemos un padre con ciertas propiedades que no importan mucho por ahora, por default todos los hijos tienen un margen, alto y un color de fondo igual, lo interesante aquí es que todos tienen un ancho que cambia de acuerdo con el tamaño de letra del padre.

Ahora imaginen todo lo que podríamos hacer, simplemente cambiando el tamaño de letra del padre.

Flexbox y calc()

Finalmente, me gustaría terminar con un ejemplo que en mi opinión es súper poderoso para hacer Responsive Design 📱 .

No me voy a centrar en explicar Flexbox 📦 ya que tengo un artículo muy completo hablando de esto, te recomiendo leerlo si vas empezando con este tema.

HTML

<div class="padre">  
  <div class="hijo"></div>
  <div class="hijo"></div>
  <div class="hijo"></div>
  <div class="hijo"></div>
  <div class="hijo"></div>
</div>  

CSS

/* Padre aplicando flexbox */
.padre {
  display: flex;
  justify-content: flex-start;
  width: 100%;
}

/* Estilos para todos los hijos */
.hijo {
  background-color: #70C1B3;
  border: 1px solid  #50514F;
  box-sizing: border-box;
  height: 100px;
  width: calc(100% / 5); /* El ancho va a ser 20% */
}

Esto es un ejemplo muy sencillo de lo que se puede hacer juntando flexbox y calc(), en donde el ancho de los hijos se divide entre cinco, esto se debe a que son cinco 🖐 los hijos que tenemos ahora, si el padre tuviera diez hijos, entonces la división sería entre diez 🔟.

Esto puede ser muy útil para usar con media queries o incluso nos puede servir para hacer un sistema de grids (grillas) con Flexbox.

Los cálculos en CSS nos dan bastantes opciones en nuestro código y cambia completamente la forma en que usamos las medidas, en mi opinión todo esto para bien, pues ya he visto bastantes sitios web que usan calc() para sus medidas.