Las medidas relativas en CSS pueden darnos muchos problemas al momento de llevarlas a cabo en CSS; aplicar porcentajes en donde existen márgenes, bordes o márgenes internos también llamados padding
es prácticamente imposible si sólo empleamos porcentajes.
Pero la gente de CSS pensó en todo y crearon una nueva función llamada calc() que es provista a partir de CSS3 con la cual podemos realizar cálculos u operaciones matemáticas; es decir, sumas, restas, multiplicaciones y por supuesto divisiones; además de esto hay una excelente noticia y es la buena acogida que ha tenido ya que es soportada por los principales navegadores modernos incluido Internet Explorer.
Cómo funciona calc en CSS
calc() es una función disponible en CSS3 que permite realizar cálculos con medidas u operaciones matemáticas desde el propio CSS: operaciones de sumar ( + ), restar ( - ), multiplicar ( * ) y división ( / ) son soportadas a través de la función calc()
.
Suma, resta, multiplica y divide distintos tipos de medidas con la función calc
Con la función calc
podemos aplicar operaciones matemáticas a los distintos tipos de medidas en una misma operación; es decir podemos hacer operaciones como la siguiente:
calc(100% - 2*5px - 2*10px - 2px);
Finalmente, asignamos la función a cualquier propiedad de medida de algún elemento HTML; por ejemplo:
.miclase { height : calc(100% - 2*5px - 2*10px - 2px); }
Cómo ves, la función calc() es ideal para trabajar con el problema más que recurrente que tenemos cuando queremos definir los márgenes de un contenedor que define sus dimensiones en porcentajes; como el mostrado anteriormente.
La función calc ideal para el responsive
Entre los cálculos que hacemos para crear sitios adaptables en base al responsive web design esta la de porcentajes (%) ampliamente utilizados para hacer que los sitios se adaptan a múltiples resoluciones:
Los porcentajes en conjunto con esta función permite personalizar a un mayor grado la exactitud de la posición de los objetos en el contenido HTML; veamos unos ejemplos para entender en detalle cómo funciona.
La función calc() en la práctica
Muchas veces queremos dibujar contenedores consecutivos que se adapten al espacio disponible y con un margen entre ellos digamos de 10 pixeles y cuando nos ponemos ha realizar cálculos como los siguientes:
![CSS Función calc con contenedores CSS Función calc() con contenedores](/public/images/example/css/css-contetendores-funcion-calc.png)
Vemos que tiene varios propiedades definidas presentes como margen (margin
), margen interno (padding
), bordes (border
), etc, lo que conlleva a aumentar el tamaño del contenedor y por ende complicar cuando queremos tener varios contenedores del mismo tamaño alineados en el eje horizontal y minimizar el espacio perdido (es decir espacio, que no forme parte del contenedor); pero con calc de CSS podemos solventar esto fácilmente.
Supongamos que queremos crear cuatro (4) contenedores que deben de estar alineados y tener el mismo ancho, largo y ocupar el mayor tamaño posible dejando un espacio entre ellos como vimos en la imagen anterior; con CSS tradicional quedaría muy mal porque si empleamos medidas estáticas en los márgenes en un punto se rompe el orden y el cálculo falla, algo similar sucede si empleamos porcentajes en todos los niveles, en donde el espacio sería demasiado grande en un punto; entonces cómo podemos hacer el cálculo.
Lo primero que se nos ocurre es colocarle a todos los contenedores con un mismo ancho (width) de 25%; además necesitaremos algunas otras propiedades como las siguientes con un cálculo fijo para el margen:
.example1 div{ float : left; margin : 10px 0 10px 10px; padding : 5px; background:#CCC; }
Y obtenemos el siguiente resultado; esto es sin emplear la función calc de CSS:
Lo que se aleja del diseño original ya que solo tres (3) de los contenedores están posicionados conjuntamente y hay algo malo con el cálculo anterior.
Problema con los cálculos: márgenes y padding de los contenedores junto con los porcentajes
Como indicamos anteriormente, cuando empleamos otras propiedades como márgenes (margin
), márgenes internos (padding
), bordes (border
) estos afectan directamente el tamaño de nuestro contenedor y por lo tanto resulta en contenedores de un tamaño algo mayor a 25%; para ser precisos y siguiendo nuestro ejemplo el tamaño de cada contenedor sería algo como lo mostrado en el siguiente cálculo:
/* ancho + margen derecho + margen izquierdo + padding derecho + padding izquierdo + borde derecho + borde izquierdo*/ largo contenedor = 25% + 10px + 10px + 5px + 5px + 3px + 3px;
O lo que es lo mismo:
largo contenedor = 25% + 2*10px + 2*5px +2*3px;
Obviamente sumando los cuatro contenedores darían un valor mayor a 100% y no podemos alinear los contenedores en la misma línea por lo dicho anteriormente y nuestro cálculo falla.
Con la función calc
podemos restar todas estas propiedades del ancho (margen (margin
), margen interno (padding
) y bordes (border
)) y obtener el efecto deseado:
width : calc(25% - 2*5px - 10px - 2px);
Un caso parecido ocurre cuando queramos calcular el largo del contenedor:
height : calc(100% - 2*5px - 2*10px - 2px);
Finalmente queda definida la regla como:
.example1 div{ float : left; margin : 10px 0 10px 10px; padding : 5px; width : calc(25% - 2*5px - 10px - 2px); min-height : calc(100% - 2*5px - 2*10px - 2px); background:#CCC; }
Ahora obtenemos como resultado:
La función calc(), contenedores y la propiedad position
Veamos otro ejemplo empleando la función calc
en conjunto de la propiedad position.
Queremos obtener el mismo efecto; es decir, alinear contenedores en el eje horizontal maximizando el espacio total en cada contenedor; pero a diferencia del caso anterior, los contenedores rompen con el flujo normal de la página a través de la propiedad position; aun así podemos ingeniarnosla y emplear la función calc de CSS:
.example1 div{ position: absolute; width : 25%; height : 60%; background:#CCC; top:calc(50% - 60% / 2); border: 1px solid #F00; }
Esta vez solo tendremos 3 contenedores al cual aplicar el cálculo y por lo tanto cada uno debe de ocupar un 33% de su espacio; en este 33% debe de comprender los márgenes (margin
), márgenes internos (padding
) y bordes (border
.
Al ser contenedores posicionados con la propiedad position, emplear propiedades como el margen no tendrán ningún efecto en el mismo, por lo tanto debemos de simular el margen con la propiedad left o right para que queden espaciados entre los contenedores:
.example1 div:nth-child(1) { left : calc(0% + 6.25%); } .example1 div:nth-child(2) { left : calc(25% + 6.50%*2); } .example1 div:nth-child(3) { left : calc(50% + 6.25%*3); }
Y obtenemos:
Cómo podemos darnos cuenta, la función calc() es ideal para realizar cálculos matemáticos sobre las proporciones y posiciones de nuestros elementos, podemos mezclar porcentajes con valores numéricos fácilmente.
Distintas unidades con la función calc de CSS3
Hasta ahora hemos empleado los píxeles en cada uno de los ejemplos anteriores que variamos los cálculos con la función calc, pero también podemos emplear otros tipos de unidades y de manera conjunta; por ejemplo:
line-height: calc(3em + 2px);
Conclusión
En definitiva, te podríamos dar muchísimos otros ejemplos, pero creo que la idea a quedado clara, la función calc()
de CSS3 permite realizar cálculos matemáticos para mezclarlos con porcentajes, píxeles y otras medidas y de esta manera adaptar perfectamente las dimensiones de un contenedor o grupo de los mismos sobre nuestra página web.
Podrás encontrar la compatibilidad entre los navegadores en el siguiente enlace calc() CSS.
![Andrés Cruz Andrés Cruz](/public/images/perfil.jpg)
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter