Imágenes responsivas

El texto en la Web se ajusta automáticamente en el borde de la pantalla para que no se desborde. Las imágenes, por otro lado, tienen un tamaño intrínseco. Si una imagen es más ancha que la pantalla, esta se desborda y el usuario tiene que desplazarse horizontalmente para verla completa.

Afortunadamente, CSS te brinda las herramientas para evitar que esto suceda.

Limita tus imágenes

En tu hoja de estilo, puedes usar max-inline-size para declarar que las imágenes nunca se podrán renderizar con un tamaño más ancho que el elemento que las contiene.

Navegadores compatibles

  • 57
  • 79
  • 41
  • 12.1

Origen

img {
  max-inline-size: 100%;
  block-size: auto;
}

También puedes aplicar la misma regla a otros tipos de contenido incorporado, como iframes y videos.

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

Con esta regla implementada, los navegadores reducen automáticamente las imágenes para que se ajusten a la pantalla.

Dos capturas de pantalla; la primera muestra una imagen que se expande más allá del ancho del navegador y la segunda muestra la misma imagen restringida dentro del viewport del navegador.
Restringir la imagen permite que los usuarios la vean toda sin desplazarse.

Si agregas un valor block-size de auto, el navegador conservará la relación de aspecto de las imágenes a medida que cambie su tamaño.

A veces, un sistema de administración de contenido (CMS) o algún otro sistema de publicación de contenido establecen las dimensiones de una imagen. Si tu diseño requiere una relación de aspecto diferente de la predeterminada del CMS, puedes usar la propiedad aspect-ratio para preservar el diseño de tu sitio:

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

Lamentablemente, esto suele significar que el navegador debe aplastar o estirar la imagen para que se ajuste al espacio deseado.

Perfil de un perro guapo y feliz con una pelota en la boca, pero la imagen está aplastada.
Si cambia la relación de aspecto de la imagen, esta se verá aplastada o estirada.

Para evitar aplastamiento y estiramientos, usa la propiedad object-fit.

Navegadores compatibles

  • 32
  • 79
  • 36
  • 10

Origen

Un valor object-fit de contain le indica al navegador que conserve la relación de aspecto de la imagen y que deje espacio en blanco alrededor de la imagen si es necesario.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

Un valor object-fit de cover le indica al navegador que conserve la relación de aspecto de la imagen y que la recorte si es necesario.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Perfil de un perro guapo y feliz con una pelota en la boca; hay espacio adicional a ambos lados de la imagen. Perfil de un perro apuesto y alegre con una pelota en la boca; la imagen está recortada en la parte superior e inferior.
La misma imagen con dos valores diferentes para el atributo "object-fit" aplicado. El primero tiene un valor de "object-fit" de "contain". El segundo tiene un valor de "object-fit" de "cover".

Puedes cambiar la posición del recorte de la imagen con la propiedad object-position. Esto ajusta el enfoque del recorte para que puedas asegurarte de que la parte más importante de la imagen siga siendo visible.

Navegadores compatibles

  • 32
  • 79
  • 36
  • 10

Origen

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}
Perfil de un perro guapo y de aspecto feliz con una pelota en la boca; la imagen solo se recortó en la parte inferior.
Puedes configurar object-position para recortar solo un lado de la imagen.

Publica tus imágenes

Esas reglas de CSS le indican al navegador cómo deseas que se rendericen las imágenes. También puedes proporcionar sugerencias en tu código HTML sobre cómo el navegador debe manejar esas imágenes.

Sugerencias de tamaños

Si conoces las dimensiones de la imagen, siempre incluye los atributos width y height. Incluso si la imagen se renderiza en un tamaño diferente debido a tu regla max-inline-size, el navegador conoce la proporción de ancho y alto y puede reservar la cantidad correcta de espacio. De esta manera, evitas que el resto del contenido salte cuando se carga la imagen.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>
En el primer video, se muestra un diseño sin dimensiones de imagen definidas. Observa cómo el texto salta cuando se cargan las imágenes. En el segundo video, se proporcionaron las dimensiones de la imagen, de modo que el navegador deja espacio para que la imagen y el texto no salten cuando se carga la imagen.

Sugerencias para la carga

Usa el atributo loading para indicarle al navegador si debe retrasar la carga de la imagen hasta que esté en el viewport o cerca de él. Para las imágenes de la mitad inferior de la página, usa un valor de lazy. El navegador no cargará las imágenes diferidas hasta que el usuario se haya desplazado lo suficiente hacia abajo como para que se muestre la imagen. Si el usuario nunca se desplaza, la imagen nunca se carga.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>
Las imágenes de carga diferida esperan hasta que el usuario esté a punto de desplazarse hacia ellas.

Para una imagen hero en la mitad superior de la página, no uses loading. Si tu sitio aplica automáticamente el atributo loading="lazy", por lo general, puedes establecer loading en el valor predeterminado de eager para evitar que las imágenes se carguen de forma diferida:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
>

Recuperar prioridad

Para imágenes importantes, como la imagen LCP, puedes priorizar aún más la carga con la prioridad de recuperación si estableces el atributo fetchpriority en high:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 fetchpriority="high"
>

Esto le indica al navegador que recupere la imagen de inmediato y con prioridad alta, en lugar de esperar hasta que el navegador haya terminado su diseño y recupere las imágenes normalmente.

Sin embargo, cuando le pides al navegador que priorice la descarga de un recurso, como una imagen, este debe reducir la prioridad de otro, como una secuencia de comandos o un archivo de fuente. Solo configura fetchpriority="high" en una imagen si es realmente vital.

Sugerencias de precarga

Es mejor evitar la precarga siempre que sea posible incluyendo todas las imágenes en el archivo HTML inicial. Sin embargo, es posible que algunas imágenes no estén disponibles, como las que agrega JavaScript o una imagen de fondo de CSS.

Puedes usar la precarga para que el navegador recupere estas imágenes importantes con anticipación. Para imágenes realmente importantes, puedes combinar esta precarga con el atributo fetchpriority:

<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">

Nuevamente, usa estos atributos con moderación para evitar anular con demasiada frecuencia la heurística de priorización del navegador. Su uso excesivo puede provocar una degradación del rendimiento.

Algunos navegadores admiten la carga previa de imágenes responsivas basadas en srcset, con los atributos imagesrcset y imagesizes. Por ejemplo:

<link rel="preload" imagesrcset="hero_sm.jpg 1x hero_med.jpg 2x hero_lg.jpg 3x" as="image" fetchpriority="high">

Mediante la exclusión del resguardo de href, puedes asegurarte de que los navegadores sin compatibilidad con srcset aún precarguen la imagen correcta.

No puedes precargar imágenes en diferentes formatos según la compatibilidad del navegador con determinados formatos. Intentar esto puede generar descargas adicionales que desperdician los datos de los usuarios.

Decodificación de imágenes

También hay un atributo decoding que puedes agregar a los elementos img. Puedes indicarle al navegador que la imagen se puede decodificar de forma asíncrona para que pueda priorizar el procesamiento de otro contenido.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

Puedes usar el valor sync si la imagen en sí es el contenido más importante que debes priorizar.

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

El atributo decoding no cambia la rapidez con la que se decodifica la imagen. Solo afecta si el navegador espera a que se produzca la decodificación de la imagen antes de renderizar otro contenido.

En la mayoría de los casos, esto no tiene mucho impacto, pero a veces puede permitir que el navegador muestre tu imagen o algún otro contenido un poco más rápido. Por ejemplo, en el caso de un documento grande con muchos elementos que tardan en renderizarse y con imágenes grandes que tardan mucho tiempo en decodificarse, configurar sync en imágenes importantes le indica al navegador que espere la imagen y la renderice a la vez. Como alternativa, puedes configurar async para permitir que el navegador muestre contenido más rápido y sin esperar a que se decodifique la imagen.

Sin embargo, la mejor opción suele ser intentar evitar tamaños excesivos de DOM y usar imágenes responsivas para reducir el tiempo de decodificación, en lugar de usar decoding.

Imágenes responsivas con srcset

Gracias a esa declaración max-inline-size: 100%, tus imágenes no pueden salir de los contenedores. Sin embargo, si un usuario tiene una pantalla pequeña y una red de ancho de banda bajo, hacer que descargue imágenes del mismo tamaño que los usuarios con pantallas más grandes desperdicia datos.

Para solucionar este problema, agrega varias versiones de la misma imagen en diferentes tamaños y usa el atributo srcset para indicarle al navegador que existen estos tamaños y cuándo usarlos.

Descriptor de ancho

Puedes definir un srcset con una lista de valores separados por comas. Cada valor es la URL de una imagen, seguida de un espacio y de algunos metadatos sobre la imagen, denominado descriptor.

En este ejemplo, los metadatos describen el ancho de cada imagen con la unidad w. Un w es el ancho de un píxel.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

El atributo srcset complementa el atributo src, en lugar de reemplazarlo. Debes tener un atributo src válido, pero el navegador puede reemplazar su valor por una de las opciones que aparecen en srcset. Para ahorrar ancho de banda, el navegador solo descarga la imagen más grande si es necesario.

Tamaños

Si usas el descriptor de ancho, también debes usar el atributo sizes para brindarle más información al navegador. Esto le indica al navegador el tamaño en el que esperas que se muestre la imagen en diferentes condiciones. Esas condiciones se especifican en una consulta de medios.

El atributo sizes toma una lista separada por comas de consultas de medios y anchos de imágenes.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

En este ejemplo, se le indica al navegador que, en un viewport con un ancho superior a 66em, la imagen no debería mostrar un ancho máximo de un tercio de la pantalla (dentro de un diseño de tres columnas, por ejemplo).

Para anchos de viewport de entre 44em y 66em, muestra la imagen en la mitad del ancho de la pantalla (como en un diseño de dos columnas).

Si el valor es más estrecho que 44em, muestra la imagen en el ancho completo de la pantalla.

Esto significa que no necesariamente se usará la imagen más grande para la pantalla más ancha. Una ventana del navegador ancha que puede mostrar un diseño de varias columnas usa una imagen que cabe en una columna, que puede ser más pequeña que una imagen usada para un diseño de una sola columna en una pantalla más estrecha.

Usa descriptores de tamaño para cambiar la disposición de la página en diferentes tamaños de pantalla.

Descriptor de densidad de píxeles

También puedes usar descriptores a fin de proporcionar una versión alternativa de las imágenes para mostrar en pantallas de alta densidad, y así mantener las imágenes nítidas en las resoluciones más altas que proporcionan.

Dos versiones de la misma imagen de un perro guapo y feliz con una pelota en la boca: una se ve nítida y la otra muy difusa.
Las imágenes con densidades de píxeles más bajas pueden verse borrosas.

Usa el descriptor de densidad para describir la densidad de píxeles de la imagen en relación con la imagen en el atributo src. El descriptor de densidad es un número seguido de la letra x, como en 1x o 2x.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

Si small-image.png tiene un tamaño de 300 x 200 píxeles y medium-image.png es de 600 x 400 píxeles, medium-image.png puede tener 2x después de él en la lista srcset.

No es necesario que uses números enteros. Si otra versión de la imagen tiene un tamaño de 450 x 300 píxeles, puedes describirla con 1.5x.

Imágenes de la presentación

Las imágenes en HTML son contenido. Es por eso que incluyes el atributo alt con una descripción de la imagen para los lectores de pantalla y los motores de búsqueda.

Si incorporas una imagen decorativa sin contenido significativo, puedes usar un atributo alt vacío.

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

Siempre debes incluir el atributo alt, incluso si está vacío. Un atributo alt vacío le indica al lector de pantalla que la imagen es presentacional. Un atributo alt faltante no proporciona esa información.

Lo ideal es que se incluyan imágenes decorativas o de presentación con CSS en lugar de HTML. HTML es para la estructura. CSS es para la presentación.

Imágenes de fondo

Usa la propiedad background-image en CSS para cargar imágenes de presentación.

element {
  background-image: url(flourish.png);
}

Puedes especificar varias opciones de imagen con la función image-set para background-image.

La función image-set en CSS funciona de manera muy similar al atributo srcset en HTML. Proporciona una lista de imágenes con un descriptor de densidad de píxeles para cada una.

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

El navegador elige la imagen más apropiada para la densidad de píxeles del dispositivo.

Hay muchos factores que se deben considerar cuando agregas imágenes a un sitio, entre los que se incluyen los siguientes:

  • Reservar el espacio adecuado para cada imagen.
  • Averiguar cuántos tamaños necesitas.
  • Decidir si la imagen es de contenido o decorativa

Vale la pena dedicar tiempo a crear imágenes correctas. Las estrategias de imágenes deficientes pueden molestar y frustrar a los usuarios. Una buena estrategia de imágenes hace que tu sitio sea ágil y nítido, independientemente del dispositivo o de la conexión de red del usuario.

Tu kit de herramientas tiene un elemento HTML más para darte más control sobre tus imágenes: el elemento picture.

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre imágenes.

Se deben agregar estilos para que las imágenes se ajusten al viewport.

Verdadero
Las imágenes sin contención serán tan grandes como su tamaño natural.
Falso
Los estilos son obligatorios.

Cuando la altura y el ancho de una imagen se forzaron a una relación de aspecto poco natural, ¿qué estilos pueden ayudar a ajustar la manera en que la imagen se ajusta a estas proporciones?

object-fit
Especifica cómo cabe la imagen con palabras clave como contain y cover.
image-fit
Esta propiedad no existe, la inventé.
fit-image
Esta propiedad no existe, la inventé.
aspect-ratio
Esto puede provocar o resolver una relación de imagen poco natural.

Si colocas height y width en tus imágenes, CSS no podrá diseñarlas de otra manera.

Verdadero
Son más como pistas que como reglas.
Falso
CSS cuenta con una gran cantidad de opciones dinámicas para ajustar el tamaño de las imágenes, incluso si la altura y el ancho están intercalados en la etiqueta.

El atributo srcset no _______ el atributo src, sino _______.

complemento, reemplaza
srcset definitivamente no reemplaza al atributo src.
reemplazar, complementa
Proporciona opciones adicionales para que el navegador elija, si es posible.

Falta un elemento alt en una imagen es igual a un objeto alt vacío.

Verdadero
Un atributo alt vacío le indica al lector de pantalla que esta imagen es presentacional.
Falso
La falta de alt no le indica nada al lector de pantalla.