Introducción a las funciones Min, Max, y Clamp de CSS

Cuando maquetamos se suelen dar situaciones particulares, como un elemento que tiene que ser más ancho que su padre pero con un valor relativo, o una tipografía fluida entre un rango de valores y dependiente del ancho de pantalla. Para igualar en código el resultado que presenta el equipo de UX/UI tenemos que ingeniar sistemas que nos permitan crear estos estilos, y es en estos casos en los que la función de CSS calc() no sólo brilla sino que es esencial ya que permite realizar cálculos matemáticos utilizando diferentes unidades, pero hoy vamos a ver otras funciones también recogidas en el documento de trabajo CSS Values and Units Module Level 4 que ya cuentan con un amplio soporte: min(), max() y clamp().

Min()

min() es una función de CSS que puede ser aplicada a cualquier propiedad que soporte alguno de los tipos <length>, <frequency>, <angle>, <time>, <percentage>, <number>, o <integer>. Es una función a la que dada una serie de valores (parámetros) separados por comas, se escoge el valor más pequeño de entre ellos para aplicarlo como valor de la propiedad.

.element {
  width: min(500px, 70%);
}

La manera de leer el ejemplo anterior sería así: “En este momento, ¿cuál es el valor más pequeño? ¿500px o el 70% del ancho del contenedor del padre?”

Si el contenedor padre midiese 1000px, estaríamos buscando el valor más pequeño entre 500px y 700px, luego el ancho serían 500px.

Sin embargo hacemos hincapié en “En este momento” porque lo interesante es que si cambia el tamaño de la pantalla o el zoom, cambiará el ancho del contenedor padre y por tanto el resultado de ese 70%. Si ahora el contenedor midiese 500px, el 70% serían 350px, luego el valor a aplicarse sería 350px y no 500px como era antes.

En realidad con esta fórmula estamos asegurando un valor máximo que no se puede sobrepasar, si la utilizamos para indicar un <width> podríamos entenderla como un equivalente a <width> y <max-width> juntos, ya que tenemos un valor <width> (70%) y un <max-width> (500px).

Idealmente los valores que se pasan a la función son de diferentes unidades o relativos puesto que si fuesen de la misma unidad y absolutos, tipo “500px, 550px” perdería el sentido la propiedad

Max()

max() es otra función de CSS que puede aplicarse a cualquier propiedad que soporte alguno de los tipos <length>, <frequency>, <angle>, <time>, <percentage>, <number>, o <integer>. De entre los parámetros separados por comas que recibe la función, escoge el mayor, que será el que se aplique como valor de la propiedad.

.element {
  width: max(40em, 98%);
}

En este caso interpretaríamos el ejemplo anterior de la siguiente manera: “En este momento, ¿qué valor es el mayor de los dos? ¿40em o el 98% del ancho del contenedor padre?”

Ya que las condiciones en las que se está renderizando el contenido pueden cambiar, la gracia y la potencia de la función radica en su re-evaluación, pudiendo de esta manera escoger el valor que mejor se ajuste en cada situación.

En este caso estamos asegurando un valor mínimo para esa propiedad, si la utilizamos para indicar un <width> podríamos entenderla como un equivalente a <width> y <min-width> juntos, ya que tenemos un valor <width> (98%) y un <min-width> (40em).

Tanto para min() como para max() el orden de los parámetros no importa ya que en ocasiones el primer parámetro será el mayor/menor y en otras lo será el segundo

Clamp()

Podemos entender clamp() como la función agrupadora de las dos anteriores. Esta necesariamente debe recibir 3 parámetros y en un orden concreto: VALOR_MINIMO, VALOR_IDEAL y VALOR_MAXIMO.

La función se resuelve con la fórmula: max(VALOR_MINIMO, min(VALOR_IDEAL, VALOR_MAXIMO)). Y si le pusiéramos palabras podríamos leerla como: “Escoge el valor mayor entre el mínimo (que funciona como límite por debajo) y el máximo que haya surgido tras resolverse la función min() entre el valor ideal y el máximo (que funcionar como límite por arriba)”.

.element {
  font-size: clamp(14px, 3em, 4rem);

  /* 
    Asumiendo que 1em = 10px, 3em = 10px * 3 = 30px
    y que 1rem = 16px, 4rem = 16px * 4 = 64px
    Lo transformaríamos en
  */
  font-size: clamp(14px, 30px, 64px);

  /* 
    Aplicando la fórmula lo volveríamos a transformar en 
  */
  font-size: max(14px, min(30px, 64px)) 
  font-size: max(14px, 30px);
  font-size: 30px;
}

Estaríamos hablando de una propiedad parecida al shorthand de flex pero que en la práctica sería como aplicar (si estuviésemos indicando un ancho), <min-width>, <max-width> y <width>

clamp(MIN, VAL, MAX) se resuelve como max(MIN, min(VAL, MAX))

Propiedades comunes y usos

.element-a {
  font-size: max(min(10%, ((1.25vw + 10px) * 0.5), 5vw), 1rem);
}

.element-b {
  font-size: max(min(10%, calc((1.25vw + 10px) * 0.5), 5vw), 1rem);
}

Uso en Sass

Al utilizar min() y max() en Sass (SCSS) ocurre que el compilador (LibSass o Ruby Sass) lanza un error por utilizar unidades incompatibles, esto se debe, como indica la documentación oficial a que estos interpretan min() y max() como las funciones propias de Sass y no como las funciones de CSS (que han llegado mucho después) y por eso para utilizar estas implementaciones recomiendan hacerlas tratándolas como una cadena de texto:

.element-c {
	width: unquote("min(500px, 98%)");
}

.element-d {
	font-size: unquote("max(min(10%, ((1.25vw + 10px) * 0.5), 5vw), 1rem)");
}

Otra solución, muy inteligente por su sencillez, la aporta Ana Tudor en un artículo en CSS Tricks titulado precisamente “Cuando Sass y las novedades de CSS entran en conflicto” al que llegué a través de la aportación del perfil de Codepen al plantear la duda en Twitter. En el artículo se trata con mucha profundidad la computación con diferentes valores no relacionados y otros casos especiales y variables nativas de CSS de por medio, pero la solución es un básico del lenguaje: Sass es case-sensitive pero CSS no, por lo que el compilador de Sass no entendería Min() como su función interna y no se produciría el error, ahora bien, el CSS resultante al no hacer esta distinción entre mayúsculas y minúsculas, interpreta de la misma manera MIN(), que Min() o min() y podríamos utilizar sin problemas estas funciones.

Conclusión

Cabe destacar que aunque clamp() es la función más compleja de las 3, es al mismo tiempo la más completa y en la práctica, tras un poco de uso te darás cuenta que será la que más utilices, si no la única.

Estas 3 funciones nos permiten añadir algo más de lógica, flexibilidad y control a nuestras hojas de estilo, lo que nos ayuda a hacer aplicaciones más potentes y enriquecerlas para conseguir resultados cada vez más exigentes. Entender el funcionamiento de min(), max() y clamp() nos va a brindar nuevas herramientas para afrontar una maqueta con más recursos y potencialmente ser más creativos. Demo

Recursos

W3C - CSS Values and Units Module Level 4

MDN

caniuse.com

SassLang min, max functions

webdesign.tutsplus.com

comments powered by Disqus

Si te ha parecido interesante

Tanto si tienes alguna duda o quieres charlar sobre este tema, como si el contenido o nuestros perfiles te parecen interesantes y crees que pdemos hacer algo juntos, no dudes en ponerte en contacto con nosotros a través de twitter o en el email hola@mamutlove.com

Actualmente estamos abiertos a nuevas propuestas para colaborar