Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=d1a81095-835f-4508-bd23-0633a7c1c2df

CSS responsive sin media queries: las funciones min(), max() y clamp()

¿Sabías que en CSS puedes definir valores de propiedades en función del viewport sin necesidad de media queries? Gracias al uso de funciones lógicas te puedes ahorrar mucho código CSS en forma de media queries innecesarias, especialmente con clamp(). Esto va a simplificar mucho tus hojas de estilos, que serán más limpias y mucho más fáciles de mantener.

Ojo, este post está pensado para gente que ya se desenvuelve con soltura en CSS. Si estás dando tus primeros pasos, aunque es interesante que sepas que estas funciones existen, quizá es mejor que primero te centres en aprender bien los fundamentos de HTML y CSS y de la maquetación web responsive.

Pero, ¿qué son las funciones de CSS?

Una función en CSS es un tipo de valor que se le asigna a una propiedad, con la peculiaridad de que este valor no es fijo y que varía en función de ciertas reglas lógicas.

La primera función en aparecer seguramente ya la conoces, es la función calc(), extremadamente útil para cálculos matemáticos en propiedades, pero en este post te presentaremos a otras tres funciones muy interesantes: min(), max() y clamp().

min()

La función min() es muy sencilla. Le pones una serie de valores separado por comas y usará la opción más pequeña.

Algo así:

width: min(60vw, 600px);
/* El valor del ancho será el más pequeño*/

max()

La función max() funciona de forma similar, pero al revés. A partir de una serie de parámetros usará el de mayor valor.

O sea, algo así:

width: max(60vw, 600px);
/* El valor del ancho será el más grande*/

En ambos casos podemos usar más de dos valores, dependerá de la cantidad de restricciones que queramos aplicar, y además el orden NO importa.

width: min(600px, 50%, 60vw);
width: min(60vw, 600px, 50%); 
/* Ambas propiedades hacen lo mismo, el valor del ancho será el más pequeño*/

width: max(600px, 50%, 60vw);
width: max(60vw, 600px, 50%);
/* Lo mismo, el valor del ancho será el más grande en ambos casos*/

Propiedades y valores min() y max()

Podremos usar min() y max() en todas aquellas propiedades cuyos valores sean: longitudes, ángulos, tiempo, frecuencia y números (enteros o no). Y lo mejor, las podemos combinar con otras funciones como calc()y clamp() (esta la veremos ahora en este mismo post).

Por ejemplo:

width: min(600px, calc(50% - 5px), 60vw);

Cuándo usar min() y max(): el truco de la luna

¿Conoces el truco para saber cuándo la luna está en cuarto creciente o menguante?

  • Cuando la luna tiene forma de "C": está Decreciendo
  • Cuando la luna tiene forma de "D": está Creciendo

Vamos, que es exactamente al revés de lo que parece.

Pues a la hora de aplicar min() y max() ocurre algo similar:

  • La función min() es ideal para establecer valores máximos, porque su valor nunca va a ser mayor que su valor absoluto más pequeño cuando mezclamos valores absolutos y relativos (estos últimos pueden variar).
  • La función max() es ideal para establecer valores mínimos, porque su valor nunca va a ser menor que su valor absoluto más grande cuando mezclamos valores absolutos y relativos (estos últimos pueden variar).

¿Te parece lioso? ¡Tranquilidad! Veamos un ejemplo con este div:

<div class="min">
        <h2><span>min()</span> - campusMVP.es</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus nulla, pretium id mattis sit amet, venenatis in dui.</p>
</div>

Y en el CSS le aplico este ancho con min():

.min {
            width: min(60vw, 600px);
            border: 2px solid rgb(39, 122, 230);
        }

Con este valor para el width, puedo estar seguro de que este div nunca será mayor de 600px. En el momento que 60vw sea mayor de 600px, la función min() aplicará un ancho de 600px, porque este será el valor mínimo, el más pequeño.  De esta forma me ahorro definir un max-width:

Y con max() sería parecido, pero al revés. A partir de este div:

<div class="max">
        <h2>max() - campusMVP.es</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus nulla, pretium id mattis sit amet, venenatis in dui.</p>
</div>

Y con este CSS:

.max {
            width: max(60vw, 600px);
            border: 2px solid rgb(236, 91, 72);
        }

No solo defino el width del div, sino que me aseguro de que, como mínimo, tendrá 600px de ancho. Si el valor de 60vw es menor de 600px, va a aplicar 600px. Así que en este caso me ahorro tener que definir un min-width:

 

La función clamp(): la guinda del pastel

Y para el final he dejado la función clamp(), mi favorita, personalmente es uno de los avances que más me han entusiasmado en CSS en los últimos años (y llevo desde 2004 gozando de este lenguaje).

Entenderás mejor cómo funciona si tienes en cuenta que "clamp" en inglés es una abrazadera de este tipo (también se le conoce como "sargento"):

No hace falta ser un experto en bricolaje para entender como funciona ¿no? Pues clamp funciona exactamente igual, marcando un máximo y un mínimo, como una combinación de min() y max(). Se le pasan tres parámetros separados por comas (en este caso no pueden ser más): el valor mínimo, el valor preferido y el valor máximo.

Así, como en esta regla:

width: clamp(100px, 20vw, 300px);

En este caso el valor del ancho será el 20% del viewport siempre que este valor sea mayor que 100px y menor que 300px. Si 20vw es menor de 100px, el valor de la propiedad será 100px (el mínimo), y si supera los 300px, lo mismo, el valor del ancho se quedará en 300px.

En clamp() los parámetros también pueden ser combinaciones de otras funciones e incluso valores negativos. Pero ten cuidado en este caso, recuerda que "-3" es un número mayor que "-4". ;-)

Usos de clamp()

Al igual que con min() y max(), se puede usar con propiedades cuyos valores sean numéricos, ángulos, tiempo, etc... pero uno de los usos más populares es la posibilidad de establecer tamaños de fuentes variables en función del viewport sin la necesidad de usar media queries.

Ejemplo de clamp() en tipografía fluida

A partir de este ejemplo de Mike Riethmuller sobre tipografía fluida usando calc() y media queries, vamos a replicar lo mismo pero usando clamp() para ahorrarnos las media queries. En el mismo archivo HTML tengo estos dos div:

    <div class="sin-clamp">
        <h2>Sin clamp() - campusMVP.es</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus nulla, pretium id mattis sit amet, venenatis in dui.</p>
    </div>
    <div class="con-clamp">
        <h2>Con clamp() - campusMVP.es</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tellus nulla, pretium id mattis sit amet, venenatis in dui.</p>
    </div>

Al div sin clamp() se le aplica este CSS:

        .sin-clamp {
            font-size: 14px;
        }

        @media screen and (min-width: 320px) {
            .sin-clamp {
                font-size: calc(14px + 8 * ((100vw - 320px) / 960));
            }
        }

        @media screen and (min-width: 1280px) {
            .sin-clamp {
            font-size: 22px;
            }
        }

Y el div con clamp() solo tiene esto:

.con-clamp {
    font-size: clamp(14px, calc(14px + 8 * ((100vw - 320px) / 960)), 22px);
}

El resultado es el mismo, tipografía variable en función del viewport simple y elegante:

En el cálculo del valor preferido no voy a entrar a fondo porque daría para otro post. Simplemente es una fórmula que calcula el tamaño de la fuente proporcionalmente al ancho del viewport.

Con clamp() nos aseguramos que este tamaño no se sale del intervalo entre 14px y 22px que se indican en el ejemplo original a través de media queries. El ahorro de código queda patente.

Y si no queremos hilar tan fino con el tamaño preferido de la fuente, aún podemos simplificarlo más, simplemente poniendo 3vw en el tamaño preferido:

.con-clamp {
    font-size: clamp(14px, 3vw, 22px);
}

Nos quedaría prácticamente igual. La diferencia es mínima:

Ejemplos de código descargables

En este zip te dejo todos los ejemplos que hemos visto, y además te añado un archivo de ejemplo con las tres funciones juntas, para que puedas probarlas con diferentes valores y apreciar mejor sus diferencias.

Espero que a partir de ahora le puedas sacar mucho partido a estas funciones. :-)

Fecha de publicación:
Pablo Iglesias Pablo Iglesias es diseñador Web. Cuenta la leyenda que, anidando listas HTML en busca de la página semánticamente perfecta, provocó un agujero espacio-temporal en IE tan grande, que en Redmond tuvieron que llamar al comando SG1 de Stargate para evitar una invasión alienígena. Puedes seguirlo en twitter ( @piglesias). Ver todos los posts de Pablo Iglesias
Archivado en: Desarrollo Web

¿Te ha gustado este post?
Pues espera a ver nuestro boletín...

Suscríbete a la newsletter

La mejor formación online para desarrolladores como tú

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.