Trabajar con tamaños dinámicos y soporte 4K

En general tenemos asumido el desarrollo adaptativo de una web con los tamaños dinámicos. Los componentes no lucen igual en un dispositivo móvil que en un monitor de escritorio y nos apoyamos en las diferentes herramientas que nos proporciona CSS para que así sea. Por ejemplo utilizando media-queries e indicando que en un tamaño de pantalla X, un texto tendrá un tamaño y, en un tamaño de pantalla 2X, tendrá un tamaño diferente. Sin embargo, podemos hacer que nuestro contenido se adapte de manera dinámica conforme el tamaño de la pantalla vaya creciendo o decreciendo sin tener que añadir saltos.

En los ejemplos que veremos a continuación me centraré en textos pero las técnicas que voy a explicar pueden aplicarse a todo tipo de elementos.

Conceptos básicos de tamaños dinámicos

Veo aconsejable repasar algunos de los conceptos que vamos a utilizar en el desarrollo de nuestros textos dinámicos. Estos son, por una parte, las unidades de longitud relativa de CSS y, por otra, unas pocas funciones de rango.

Unidades de longitud relativa

CSS tiene dos tipos de unidades de longitud: absolutas y relativas. En el primer caso, las unidades de longitud absolutas, el tamaño será inmutable a todo cambio. El ejemplo más común de unidad absolute es el pixel (px) pero existen otras menos comunes aunque igual de válidas como points (pt) o centimeters (cm).

En este artículo nos vamos a centrar en las unidades de longitud relativas. Con relativas queremos decir qué son mutables y van a escalar en función de varios factores dependiendo del tipo de medida utilizada y de ciertas propiedades que, estando en niveles de jerarquía superior, afectarán a nuestra unidad de medida relativa. En nuestro caso nos vamos a centrar principalmente en emrem y vw, pero creo conveniente mencionar que hay muchas más a cada cual más interesante y no hay que descartar su uso.

EM (Font size del padre)

EM utiliza como referencia el font-size del primer padre que lo tuviese. Veamos un ejemplo:

.parent
  font-size: 20px

.child
  font-size: 3em // Equivaldría a 60px

<div class="parent">
  <p class="child">
    Hello world!
  </p>
</div>

En este caso la clase .child tiene un padre con el font-size de 20px por lo que multiplicaríamos su font-size por 3 y obtendríamos un resultado de 60px en font-size de la clase .child.

Hay que tener en cuenta que el propio font-size de una clase afecta a sus otras propiedades en caso de tener valores relativos utilizando em.

.child
  font-size: 15px
  width: 2em // Equivaldría a 30px

Sabiendo esto podemos imaginar fácilmente cómo podemos escalar el contenido de nuestros componentes modificando una sola propiedad.

REM (Font size del elemento root)

Las propiedades con valores rem tienen en cuenta el font-size del componente root. Esto quiere decir que sólo se verán afectadas y escalaran si éste cambia su font-size. Veamos un nuevo ejemplo.

:root
  font-size: 20px
  @media only screen and (min-width: 1024px)
    font-size: 30px

.component
  font-size: 2rem // Equivaldría a 40px y 60px con la media query a 1024px

Teniendo en cuenta podemos hacernos una idea de la poténcia de su uso. Podemos alterar el tamaño de todo el contenido de nuestra web desde un solo punto.

VW (1% del tamaño horizontal del viewport)

En el caso de VW utilizamos como referencia el tamaño horizontal de la pantalla de nuestro dispositivo. Por lo tanto 100vw equivaldría al 100% del ancho de la pantalla. Si por ejemplo la pantalla midiese 1024px de ancho y nuestra medida es 25vw, el resultado serían 256px.

Funciones de rango

En este articulo vamos a centrarnos en 3 funciones que nos ofrece CSS, estas son min()max() y clamp(). Son funciones que reciben un rango variable y un mínimo, un máximo o ambos según el caso.

Función max()

La función max() recibe como primer parámetro el rango variable de escalado que necesitemos y como segundo parámetro el valor mínimo del que no queremos que baje.

Pongamos un ejemplo:

h1
  font-size: max(2vw, 30px)

Si tuviésemos una pantalla de 1000px de tamaño 2vw equivaldrían a 20px pero como hay un mínimo de 30px este sería el tamaño del font size. En caso de ser mayor a 30px escalaría según el cálculo de 2vw.

Función min()

Para evitar ser redundantes, diremos que el funcionamiento de min() es igual a la función  max() pero el segundo parámetro que recibe la función es el valor máximo que no queremos sobrepasar.

Función clamp()

La función clamp() recibe tres parámetros. El primero es el valor mínimo del que no queremos que baje; el segundo el rango variable de escalado; el tercero el valor máximo que no queremos que sobrepase.

Veamos un ejemplo:

h1
  font-size: clamp(30px, 2vw, 60px)

Si tuviésemos una pantalla de 1000px como en el ejemplo de la función max() el funcionamiento sería idéntico, el tamaño mínimo nunca estaría por debajo de 30px.

Pongamos otro caso en el que tenemos una pantalla 4K de 3840px en la que 2vw equivaldrían a 76,8px. En este caso el tamaño máximo del font-size sería de 60px puesto que es el máximo de la función clamp().

tamaños_dinámicos_recap

Una pequeña recapitulación

En este punto ya tenemos todas las herramientas para escalar nuestros textos de manera dinámica. Utilizaremos unidades de longitud relativas para que los textos escalen y utilizaremos las funciones de rango para que este escalado no exceda los mínimos o máximos deseados.

Soporte 4K

Teóricamente con lo aprendido ya podemos dar soporte 4K. Pongamos de nuevo uno de los ejemplos vistos anteriormente.

h1
  font-size: max(2vw, 30px)

Veamos que tamaño tendrá la fuente en varios breakpoints.

Pantalla de 768px

2vw equivaldrían a 15,36px. Puesto que el mínimo que nos permite nuestra función son 30px, el font-size será de 30px.

Pantalla de 1024px

2vw equivaldrían a 20,48px. Puesto que el mínimo que nos permite nuestra función son 30px, el font-size será de 30px.

Pantalla de 1920px

2vw equivaldrían a 38,4px. Puesto que 38,4px > 30px el font-size será de 38,4px.

Pantalla de 3840px

2vw equivaldrían a 76,8px. Puesto que 76,8px > 30px el font-size será de 76,8px.

Hasta el infinito y más allá

Teniendo en cuenta que no tenemos un máximo, nuestro texto escalará hasta infinitamente independientemente del tamaño de la pantalla. Teóricamente estamos ya dando soporte 4K e, incluso, a mayores resoluciones pero no siempre tendremos la suerte de que se ajuste a un diseño y escale manteniendo el tamaño de estilo deseado.

Un nuevo mundo de posibilidades

Llegados a este punto se abren varios caminos para que nuestro contenido escale dinámicamente. Podríamos por ejemplo utilizar la función clamp() utilizando unidades de longitud relativa para los parámetros min y max.

.parent
  font-size: 2vw

h1
  font-size: clamp(1rem, 2em, 6rem)

<div class="parent">
  <h1>Hello world!</h1>
</div>

Veamos cómo se comportará nuestro H1 en el ejemplo anterior.

Empecemos por el tamaño mínimo del texto. Éste será de 16px, esto es debido a que el tamaño mínimo es de un 1rem y daremos por hecho que el font-size por defecto del navegador es de 16px aunque, si bien es lo más común, puede variar dependiendo del navegador. Este tamaño se mantendrá inalterable hasta que el tamaño de pantalla sea igual o superior a 401px tal que 2vw de 401px es igual a 8,02px y 2em de 8,02px es igual a 16,04px.

El texto escalará según el font-size de su padre hasta que la pantalla tenga un tamaño de 4800px ya que 2vw de 4800px equivalen a 96px (6rem).

Como hemos comentado anteriormente, es raro que nuestros diseños se adapten a nuestro escalado sin más, por lo que podemos incluir el uso de media-queries para adaptarnos a diferentes dispositivos según convenga.

Otra técnica sería utilizar unidades REM y modificar el font-size del elemento root según el tamaño del viewport, por lo que todo el contenido de nuestra web que utilizase unidades REM escalaría de manera dinámica. Esto no es descabellado puesto que si bien los ejemplos mostrados son sencillos, la realidad es algo más compleja.

Un componente simple con un título, un texto y una imagen tiene varias propiedades a controlar si aplicamos un escalado dinámico. Algunos de los más comunes serían font-sizemarginspaddingsline-height, el tamaño de la imágen, etc. Además, estas propiedades puede verse alteradas si el diseño cambia de un dispositivo a otro. Por ejemplo un display en columna en versión mobile y uno horizontal en desktop.

codigo

Conclusión

CSS nos proporciona todas las herramientas necesarias para que el contenido de nuestra web se adapte a cualquier dispositivo independientemente del tamaño de estos. De nosotros depende cómo y cuándo utilizar estas herramientas, cuáles se adaptan mejor a nuestros diseños y ¿por qué no?, con cuáles nos sentimos más cómodos.

La teoría es sencilla y ponerlo en práctica no es complicado si tenemos controlados todos los factores que afectan a los tamaños y los espaciados.

Es innegable que si bien los monitores Full HD copan una gran parte del mercado, los monitores de alta resolución cada vez son más comunes y no podemos olvidarnos de ellos. CSS está preparado pero ¿lo estamos nosotros?

Frontend

Picture of Fernando Arenas

Fernando Arenas

Me encanta que los planes salgan bien para que el front se vean bien. React/Vue.
Picture of Fernando Arenas

Fernando Arenas

Me encanta que los planes salgan bien para que el front se vean bien. React/Vue.

We are HIRING!

What Can We Do