La propiedad aspect-ratio de CSS

Es la propiedad CSS que ayuda a mantener el espaciado en los diseños responsivos.

Relación de aspecto

Navegadores compatibles

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 89.
  • Safari: 15.

Origen

La relación de aspecto se suele expresar como dos números enteros y dos puntos en las dimensiones de ancho:alto o x:y. Las relaciones de aspecto más comunes para la fotografía son 4:3 y 3:2, mientras que los videos y las cámaras para consumidores más recientes suelen tener una relación de aspecto de 16:9.

Dos imágenes con la misma relación de aspecto Uno es de 634 × 951 px y el otro de 200 × 300 px. Ambos tienen una relación de aspecto de 2:3.
Dos imágenes con la misma relación de aspecto. Uno es de 634 × 951 px y el otro de 200 × 300 px. Ambas tienen una relación de aspecto de 2:3.

Con la llegada del diseño responsivo, mantener la relación de aspecto resulta cada vez más importante para los desarrolladores web, especialmente debido a que las dimensiones de las imágenes difieren y los tamaños de los elementos cambian en función del espacio disponible.

Estos son algunos ejemplos de situaciones en las que es importante mantener la relación de aspecto:

  • Crear iframes responsivos, en los que ocupan el 100% del ancho de un elemento superior y la altura debe seguir siendo una proporción de viewport específica
  • Creación de contenedores de marcadores de posición intrínsecos para imágenes, incorporaciones y videos para evitar que se modifique el diseño cuando los elementos se carguen y ocupen espacio
  • Crear un espacio uniforme y responsivo para visualizaciones de datos interactivas o animaciones SVG
  • Crear un espacio uniforme y responsivo para componentes de varios elementos, como tarjetas o fechas de calendario
  • Crea un espacio uniforme y responsivo para varias imágenes de diferentes dimensiones (se puede usar junto con object-fit).

Ajuste de objetos

Definir una relación de aspecto nos ayuda a ajustar el tamaño del contenido multimedia en un contexto responsivo. Otra herramienta de este bucket es la propiedad object-fit, que permite a los usuarios describir cómo un objeto (como una imagen) dentro de un bloque debe llenarlo:

Visualización de la demostración de ajuste de objetos
Se muestran varios valores de object-fit. Consulta la demostración en Codepen.

Los valores initial y fill vuelven a ajustar la imagen para que ocupe todo el espacio. En nuestro ejemplo, esto hace que la imagen se vea comprimida y desenfocada, ya que vuelve a ajustar los píxeles. No es ideal. object-fit: cover usa la dimensión más pequeña de la imagen para llenar el espacio y recorta la imagen para que se ajuste en función de esta dimensión. Se “acerca” en su límite más bajo. object-fit: contain garantiza que toda la imagen siempre sea visible, por lo que es lo opuesto a cover, que toma el tamaño del límite más grande (en nuestro ejemplo anterior, este es el ancho) y cambia el tamaño de la imagen para mantener su relación de aspecto intrínseca mientras se ajusta al espacio. El caso de object-fit: none muestra la imagen recortada en su centro (posición predeterminada del objeto) en su tamaño natural.

object-fit: cover suele funcionar en la mayoría de las situaciones para garantizar una interfaz uniforme y agradable cuando se trata de imágenes de diferentes dimensiones. Sin embargo, se pierde información de esta manera (la imagen se recorta en sus bordes más largos).

Si estos detalles son importantes (por ejemplo, cuando se trabaja con una imagen en plano de productos de belleza), no se acepta recortar contenido importante. Por lo tanto, la situación ideal sería imágenes responsivas de diferentes tamaños que se ajusten al espacio de la IU sin recortarse.

El hack anterior: Mantén la relación de aspecto con padding-top

Usar padding superior para establecer una relación de aspecto de 1:1 en las imágenes de vista previa de la publicación dentro de un carrusel
Usar padding-top para establecer una relación de aspecto de 1:1 en las imágenes de vista previa de la publicación dentro de un carrusel

Para que sean más responsivas, podemos usar la relación de aspecto. Esto nos permite establecer un tamaño de proporción específico y basar el resto del contenido multimedia en un eje individual (altura o ancho).

Una solución multinavegador actualmente aceptada para mantener la relación de aspecto en función del ancho de una imagen se conoce como "Padding-Top Hack". Esta solución requiere un contenedor superior y un contenedor secundario ubicado en absoluto. Luego, se calcularía la relación de aspecto como un porcentaje para establecerla como padding-top. Por ejemplo:

  • Relación de aspecto de 1:1 = 1/1 = 1 = padding-top: 100%
  • Relación de aspecto de 4:3 = 3 / 4 = 0.75 = padding-top: 75%
  • Relación de aspecto de 3:2 = 2/3 = 0.66666 = padding-top: 66.67%
  • Relación de aspecto de 16:9 = 9/16 = 0.5625 = padding-top: 56.25%

Ahora que identificamos el valor de la relación de aspecto, podemos aplicarlo a nuestro contenedor superior. Consulta el siguiente ejemplo:

<div class="container">
  <img class="media" src="..." alt="...">
</div>

Luego, podríamos escribir el siguiente CSS:

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

Se mantiene la relación de aspecto con aspect-ratio

Usar la relación de aspecto para establecer una relación de aspecto de 1:1 en las imágenes de vista previa de la publicación dentro de un carrusel
Usa aspect-ratio para establecer una relación de aspecto de 1:1 en las imágenes de vista previa de las publicaciones dentro de un carrusel.

Lamentablemente, calcular estos valores de padding-top no es muy intuitivo y requiere un posicionamiento y una sobrecarga adicionales. Con la nueva propiedad CSS intrínseca aspect-ratio, el lenguaje para mantener las relaciones de aspecto es mucho más claro.

Con el mismo lenguaje de marcado, podemos reemplazar padding-top: 56.25% por aspect-ratio: 16 / 9 y configurar aspect-ratio en una proporción especificada de width/height.

Usa padding-top
.container {
  width: 100%;
  padding-top: 56.25%;
}
Usa aspect-ratio
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

Usar aspect-ratio en lugar de padding-top es mucho más claro y no revisa la propiedad de padding para hacer algo fuera de su alcance habitual.

Esta nueva propiedad también agrega la capacidad de establecer la relación de aspecto en auto, donde "los elementos reemplazados por una relación de aspecto intrínseca usan esa relación de aspecto; de lo contrario, el cuadro no tiene una relación de aspecto preferida". Si se especifican auto y <ratio> juntos, la relación de aspecto preferida es la relación especificada de width dividida por height, a menos que sea un elemento reemplazado con una relación de aspecto intrínseca, en cuyo caso se usa esa relación de aspecto.

Ejemplo: Coherencia en una cuadrícula

Esto también funciona muy bien con los mecanismos de diseño de CSS, como CSS Grid y Flexbox. Considera una lista con elementos secundarios en la que deseas mantener una relación de aspecto de 1:1, como una cuadrícula de íconos de patrocinadores:

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
Imágenes en una cuadrícula con su elemento superior en varias dimensiones de relación de aspecto. Mira la demostración en CodePen.

Ejemplo: Cómo evitar el cambio de diseño

Otra gran característica de aspect-ratio es que puede crear espacio para marcadores de posición para evitar el desplazamiento del diseño acumulativo y ofrecer mejores Web Vitals. En este primer ejemplo, cargar un recurso desde una API como Unsplash crea un cambio de diseño cuando se termina de cargar el contenido multimedia.

Video del cambio de diseño acumulado que ocurre cuando no se configura ninguna relación de aspecto en un recurso cargado. Este video se grabó con una red 3G emulada.

Por otro lado, el uso de aspect-ratio crea un marcador de posición para evitar este cambio de diseño:

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
El video con una relación de aspecto establecida se establece en un activo cargado. Este video se grabó con una red 3G emulada. Mira la demostración en CodePen.

Sugerencia adicional: Atributos de imagen para la relación de aspecto

Otra forma de establecer la relación de aspecto de una imagen es a través de los atributos de imagen. Si conoces las dimensiones de la imagen con anticipación, es una práctica recomendada establecerlas como width y height.

En nuestro ejemplo anterior, sabiendo que las dimensiones son de 800 px por 600 px, el marcado de la imagen se vería de la siguiente manera: <img src="image.jpg" alt="..." width="800" height="600">. Si la imagen enviada tiene la misma relación de aspecto, pero no necesariamente esos valores de píxeles exactos, aún podríamos usar los valores de atributos de imagen para establecer la relación, combinados con un estilo de width: 100% para que la imagen ocupe el espacio adecuado. Todo junto se vería de la siguiente manera:

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

Al final, el efecto es el mismo que establecer aspect-ratio en la imagen a través de CSS, y se evita el cambio de diseño acumulativo (consulta la demostración en Codepen).

Conclusión

Con la nueva propiedad aspect-ratio de CSS, que se lanzará en varios navegadores modernos, mantener las relaciones de aspecto adecuadas en tus contenedores de diseño y contenido multimedia se vuelve un poco más sencillo.

Fotos de Amy Shamblen y Lionel Gustave a través de Unsplash.