Funciones matemáticas CSS: calc, min, max, clamp

Publicado: 2022-03-20
Introducción » Las funciones lógicas CSS calc() , clamp() , min() y max() son compatibles con todos los navegadores web modernos. Pero, a pesar de estar fácilmente disponibles, una simple búsqueda en GitHub nos dice que la adopción de estas funciones ha sido lenta. Entonces, ¿cómo los usamos exactamente para crear experiencias de diseño fluidas y receptivas? Vamos a averiguar.

Tabla de contenido
  • calcular()
  • min()
  • máx()
  • abrazadera()
  • Creación de una barra lateral receptiva con cuadrícula
  • Aplicación de un espacio de respuesta para diseños Flexbox
  • Puedo usar: El soporte está ahí
  • Conclusión

Sé lo que podrías estar pensando: “¿Matemáticas? Qué asco. Quítalo de mi vista. . Pero, pregúntese: ¿tiene la fuerza de voluntad para resistir la satisfacción de los contenedores anidados perfectamente alineados?

Sabes, después de escribir mi artículo sobre varios trucos de CSS (algunas publicaciones lo recogieron) vi tráfico que llegaba al sitio por palabras clave como "cómo centrar un elemento div", lo cual es gracioso porque nunca mencioné eso en el artículo en concreto. Pero demuestra que los desarrolladores necesitan acceso a fragmentos rápidos que se puedan volver a implementar con facilidad.

Como tal, esa será la premisa de este tutorial.

 Actualización: me puse a escribir un tutorial detallado para centrar elementos en CSS.

Me centraré en el tema de las funciones matemáticas de CSS en el contexto de lograr varios resultados de diseño. Por ejemplo , cómo crear un contenedor receptivo con unas pocas líneas de CSS, cómo agregar relleno adaptativo y cómo hacer que esa barra lateral se comporte realmente como una barra lateral.

Echemos un vistazo.


calcular()

La función calc() admite cuatro operaciones aritméticas: suma (+), resta (-), multiplicación (*) y división (/). La función se usa principalmente para calcular el ancho y el alto dinámicos del contenedor para crear experiencias de diseño adaptables.

ejemplo de código

 .calc { background: #c8e6f5; padding: 10px 20px; width: calc(100% - 200px); } .no-calc { background: #c8e6f5; padding: 10px 20px; margin-top: 10px; } <div class="calc">100% – 200px</div> <div class="no-calc">Default container width</div>

Y este sería el resultado:

100% – 200px
Ancho de contenedor predeterminado

Pero, donde calc() se destaca más es cuando se usa para organizar elementos con un valor específico en mente. Por lo general, un diseño receptivo se lograría buscando puntos de interrupción específicos y luego escribiendo su lógica individualmente. Con calc() , podemos lograr un diseño receptivo con solo una especificación, lo que lo hace mucho más fácil de mantener.

Veamos un ejemplo concreto usando display: flex; . Nuestro objetivo es crear 3 elementos uno al lado del otro que estén vinculados al ancho (100%) del contenedor. También queremos agregar un espacio de 30 px entre cada elemento y, por supuesto, ¡necesitamos que responda!

ejemplo de código

 <style> .calc-container-flex { display: flex; justify-content: center; } .calc-container-style .item { background: #fff2ea; padding: 20px 0; width: calc((100% - 90px)/3); text-align: center; } .calc-container-style .item + .item { margin-left: 30px; } </style> <div class="calc-container-flex calc-container-style"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div>

Y aquí puedes cambiar el tamaño del resultado para ver cómo funciona:

1
2
3

Como queremos tener un espacio de 30 px entre cada elemento, restamos 90 px del ancho inicial del contenedor (100 %) y lo dividimos entre 3 para especificar cuántos elementos tenemos.

A medida que cambia el tamaño del resultado anterior, notará que todos los elementos respetan su espacio respectivo sin dejar de responder al ancho del contenedor. Con buena pinta.


min()

La función min() se usa para establecer el valor mínimo aceptable. Toma 2 especificaciones diferentes separadas por una coma y admite expresiones aritméticas.

Digamos que especifica font-size: min(25px,1vw); – en este ejemplo, el tamaño de fuente nunca será mayor a 25px y se reducirá a 1vw dependiendo del tamaño de la ventana gráfica.

También podemos usar min() para manipular el ancho de los elementos del contenedor.

ejemplo de código

 .min-sample-box-container { width: 100%; max-width: 1000px; } .min-sample-box { background: #fff2ea; padding: 15px 30px; width: min(70%, 800px); } <div class="min-sample-box-container"> <div class="min-sample-box">min() example - 800px limit</div> </div>

Intenta cambiar el tamaño de esto:

min() ejemplo – límite de 800px

En este contexto, el elemento div dentro de nuestro contenedor no puede exceder los 800 px de ancho a pesar de que el contenedor tenga un ancho máximo de 1000 px.


máx()

La función max() nos permite hacer exactamente lo contrario. De los dos valores, especificamos dentro de max() : se priorizará el más grande.

ejemplo de código

 .max-sample-box-container { width: 100%; max-width: 1000px; } .max-sample-box { background: #fff2ea; padding: 15px 30px; width: max(70%, 200px); } <div class="max-sample-box-container"> <div class="max-sample-box">max() example - 200px limit</div> </div>

Intente cambiar el tamaño de esto en un contenedor más pequeño para ver qué sucede:

ejemplo max() – límite de 200px

Como puede ver, el contenedor respeta el width: 100%; pero no va por debajo de la marca de 200 px especificada, ya que es el valor más grande para el contenedor.

La característica max() es particularmente útil cuando se aplican márgenes de respuesta. Por lo general, lo que sucede es que cuando usa muchos elementos más pequeños en un diseño, obstruyen la pantalla una vez que se cambia el tamaño. Con max() podemos priorizar un margen específico para respetar el ancho del contenedor.

ejemplo de código

 .max-margin-container { display: flex; flex-wrap: wrap; width: 100%; } .max-margin-container li { background: #fff2ea; color: #fff; padding: 3px 25px; min-width: 60px; text-align: center; margin: 0 max(4px,1vw) max(4px,1vw) 0; } <ul class="max-margin-container"><li>calc()</li><li>min()</li><li>max()</li><li>clamp()</li> <li>sin()</li><li>cos()</li><li>tan()</li><li>acos()</li><li>asin()</li><li>atan()</li> <li>atan2()</li><li>hypot()</li><li>sqrt()</li><li>pow()</li></ul>

Intenta cambiar el tamaño de la lista para verla en acción:

  • calcular()
  • min()
  • máx()
  • abrazadera()
  • pecado()
  • porque()
  • broncearse()
  • acos()
  • como en()
  • un bronceado()
  • atan2()
  • hipot()
  • sqrt()
  • pow()

Cambiar la ventana gráfica de su navegador es un mejor ejemplo de esta demostración en acción. Y, sí, ¡esas son, de hecho, todas las funciones matemáticas disponibles en CSS!

Como puede ver, a pesar de que cambia el ancho de la ventana gráfica, los botones mantienen su margen de 4px en todo momento.


abrazadera()

La función clamp() se usa para definir el rango aceptable de varios valores para un elemento de diseño: mínimo , preferido y máximo . Más comúnmente, clamp() se usa para establecer un rango de valores aceptables para la tipografía, para crear el efecto de una tipografía fluida .

Es, en esencia, la culminación de las funciones min() y max() .

Un ejemplo:

font-size: clamp(1rem, 4vw + 1rem, 4rem);

Y esto es lo que parece:

Ejemplo de función de abrazadera CSS

En este contexto, diseñamos nuestro encabezado h2 con un valor mínimo de 1rem , un máximo de 4rem y establecemos nuestro tamaño preferido en 4vw (unidades de ventana gráfica) + 1rem . Como puede ver en la demostración anterior, a medida que nuestra ventana gráfica cambia, también lo hace el tamaño de fuente del encabezado.

Esto también concluye nuestra introducción a las funciones matemáticas más compatibles en CSS.

La siguiente sección está dedicada íntegramente a ejemplos y varios casos de uso en los que se pueden aplicar estas funciones. En general, nuestro enfoque está en la creación de elementos de diseño receptivos que, de otro modo, tendrían que escribirse a través de consultas de medios.

Creación de una barra lateral receptiva con cuadrícula

¿Puede implementar una barra lateral receptiva completamente funcional con solo 2 líneas de CSS?

Absolutamente.

Para esta demostración, vamos a crear una barra lateral receptiva usando display: grid; y personalizar la capacidad de respuesta con grid-template-columns . Específicamente, usaremos las funciones fit-content y minmax() para establecer nuestras restricciones.

ejemplo de código

 .grid-sidebar-demo { display: grid; grid-template-columns: fit-content(25ch) minmax(min(55vw, 35ch), 1fr) }

Aquí está el resultado:

El contenido de la barra lateral Su contenido en la página

Entendamos lo que está pasando aquí.

Primero, aplicamos fit-content para declarar el tamaño preferido de nuestra barra lateral. El valor que especificamos aquí empujará la barra lateral para que crezca (según el tamaño de la ventana gráfica) o se reducirá en pantallas más pequeñas. Todo el tiempo teniendo en cuenta la cantidad de contenido que tiene en la barra lateral.

Después, aplicamos minmax() porque no queremos que la barra lateral se superponga con el área de contenido de la página. En nuestro caso, establezca en húmedo un valor de 55vw que se usará para la pantalla móvil y 35ch que se usará para ventanas de visualización más grandes. Y, por último, aplicamos la unidad de fracción específica de Grid para llenar el espacio cuando la ventana gráfica lo permita.

Aplicación de un espacio de respuesta para diseños Flexbox

Este es un ejemplo similar al relleno receptivo que vimos anteriormente. Pero para esta demostración, usamos flexbox y la propiedad gap junto con clamp() .

ejemplo de código

 .gap-boxes-container { display: flex; flex-wrap: wrap; gap: clamp(5px, 1vw, 25px); place-content: center; } .gap-box { display: inline-flex; width: 100px; height: 100px; background-color: #fff2ea; align-items: center; justify-content: center; } <div class="gap-boxes-container"> <div class="gap-box">1</div> <div class="gap-box">2</div> <div class="gap-box">3</div> <div class="gap-box">4</div> </div>

Pruébalo:

1
2
3
4

Una vez más, esta demostración funciona mejor cuando cambia el tamaño de la ventana del navegador real.

Especificando gap: clamp(5px, 1vw, 25px); le estamos diciendo al navegador que adapte el espacio entre cada columna en función del tamaño de la ventana gráfica. Entonces, si la ventana excede 1vw, la brecha aumenta a 25 px, mientras que una ventana pequeña la reducirá a 5 px (en dispositivos móviles, por ejemplo).

Por cierto, es posible que haya notado que utilicé una propiedad interesante para centrar las cajas contenedoras, es place-content: center; . Esta es una propiedad abreviada que admite el posicionamiento del contenido en varias direcciones. Puedes leer más sobre esto en MDN.

Puedo usar: El soporte está ahí

Conclusión

¿Estás emocionado de probar algunos de estos conceptos en tu próximo proyecto?

Debo decir que CSS ha recorrido un largo camino desde principios de la década de 2010. De hecho, si podemos hacer la mayor parte de nuestro estilo receptivo sin consultas de medios, atraerá a más desarrolladores que quieran escribir código y no preocuparse por la compatibilidad entre varios dispositivos.

¡Gracias por leer y diviértanse!