Imágenes responsivas

El texto en la Web se une 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, se desborda y el usuario tiene que desplazarse horizontalmente para verla por completo.

Afortunadamente, el CSS te brinda 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 pueden renderizar en un tamaño más ancho que su elemento contenedor.

Browser Support

  • Chrome: 57.
  • Edge: 79.
  • Firefox: 41.
  • Safari: 12.1.

Source

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

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

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

Con esta regla, 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.
Limitar la imagen permite que los usuarios la vean por completo sin desplazarse.

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

A veces, un sistema de administración de contenido (CMS) o algún otro sistema de entrega de contenido establece 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 comprimir o estirar la imagen para que se ajuste al espacio previsto.

Perfil de un perro apuesto y alegre con una pelota en la boca, pero la imagen está aplastada.
Cambiar la relación de aspecto de la imagen hace que se vea comprimida o estirada.

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

Browser Support

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

Source

Un valor object-fit de contain le indica al navegador que preserve la relación de aspecto de la imagen, dejando espacio vacío alrededor de ella si es necesario.

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

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

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Perfil de un perro apuesto y feliz con una pelota en la boca. Hay espacio adicional a ambos lados de la imagen. Perfil de un perro apuesto y feliz con una pelota en la boca. La imagen se recortó en la parte superior e inferior.
La misma imagen con dos valores diferentes para "object-fit" aplicados. 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, de modo que puedas asegurarte de que la parte más importante de la imagen siga siendo visible.

Browser Support

  • Chrome: 32.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 10.

Source

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}
Perfil de un perro apuesto y 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 controlar esas imágenes.

Sugerencias para el tamaño

Si conoces las dimensiones de tu 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 aún conoce la proporción de ancho a alto y puede reservar la cantidad correcta de espacio. De esta manera, evitas que el resto de tu contenido se desplace 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, por lo que el navegador deja espacio para la imagen y el texto no se mueve 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 que se encuentran debajo de la mitad inferior de la página, usa un valor de lazy. El navegador no cargará imágenes diferidas hasta que el usuario se desplace lo suficiente hacia abajo como para que la imagen esté a punto de aparecer. 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 con carga diferida esperan a cargarse hasta que el usuario está a punto de desplazarse hasta 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"
>

Prioridad de recuperación

En el caso de las imágenes importantes, como la imagen de LCP, puedes priorizar aún más la carga con la prioridad de recuperación. Para ello, establece 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 alta prioridad, en lugar de esperar hasta que el navegador haya terminado su diseño y recupere las imágenes de forma normal.

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

Sugerencias para la precarga

Es mejor evitar la carga previa siempre que sea posible. Para ello, incluye 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 carga previa para que el navegador recupere estas imágenes importantes con anticipación. En el caso de las imágenes realmente importantes, puedes combinar esta carga previa con el atributo fetchpriority:

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

Una vez más, usa estos atributos con moderación para evitar anular las heurísticas de priorización del navegador con demasiada frecuencia. El uso excesivo puede provocar una degradación del rendimiento.

Algunos navegadores admiten la carga previa de imágenes responsivas según 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">

Si excluyes el resguardo de href, puedes asegurarte de que los navegadores sin compatibilidad con srcset carguen previamente la imagen correcta.

No puedes precargar imágenes en diferentes formatos según la compatibilidad del navegador con ciertos formatos. Si intentas hacerlo, es posible que se generen descargas adicionales que desperdicien 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 priorice 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 elemento de contenido más importante que se debe 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 velocidad con la que se decodifica la imagen. Solo afecta si el navegador espera a que se produzca esta decodificación de imágenes 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 cualquier 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 en decodificarse, configurar sync en imágenes importantes le indica al navegador que espere a la imagen y renderice ambas 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 de DOM excesivos 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 sus contenedores. Sin embargo, si un usuario tiene una pantalla pequeña y una red de baja amplitud de banda, se desperdician datos si se le hace descargar imágenes del mismo tamaño que los usuarios con pantallas más grandes.

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 estos tamaños existen 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, luego, de algunos metadatos sobre la imagen, llamados descriptores.

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. Aún debes tener un atributo src válido, pero el navegador puede reemplazar su valor por una de las opciones que se enumeran 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 proporcionarle 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 contenido multimedia.

El atributo sizes toma una lista de consultas de medios y anchos de imagen separados por comas.

<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, le indicas al navegador que, en un viewport con un ancho superior a 66em, debe mostrar la imagen con un ancho no superior a 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).

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

Esto significa que la imagen más grande no se usará necesariamente para la pantalla más ancha. Una ventana de navegador ancha que puede mostrar un diseño de varias columnas usa una imagen que se ajusta a una columna, que puede ser más pequeña que una imagen que se usa 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 tu página en diferentes tamaños de pantalla.

Descriptor de densidad de píxeles

También puedes usar descriptores para proporcionar una versión alternativa de las imágenes que se muestren en pantallas de alta densidad, de modo que las imágenes se vean nítidas en las resoluciones más altas que proporcionan.

Dos versiones de la misma imagen de un perro apuesto y feliz con una pelota en la boca, una imagen nítida y la otra desenfocada.
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 del 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 por 200 píxeles y medium-image.png es de 600 por 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 presentación

Las imágenes en HTML son contenido. Es por eso que debes incluir 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 a un lector de pantalla que la imagen es de presentación. Un atributo alt faltante no proporciona esa información.

Lo ideal es que las imágenes de presentación o decorativas se incluyan con CSS en lugar de HTML. El HTML es para la estructura. El 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 imágenes candidatas con la función image-set para background-image.

La función image-set en CSS funciona de manera 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 adecuada para la densidad de píxeles del dispositivo.

Existen muchos factores que debes tener en cuenta cuando agregas imágenes a tu sitio, entre los que se incluyen los siguientes:

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

Vale la pena tomarse el tiempo para que las imágenes sean correctas. Las estrategias de imágenes deficientes pueden ser irritantes y frustrantes para los usuarios. Una buena estrategia de imágenes hace que tu sitio se sienta ágil y nítido, independientemente del dispositivo o la conexión de red del usuario.

Hay un elemento HTML más en tu kit de herramientas que te brinda más control sobre tus imágenes: el elemento picture.

Verifica tu comprensión

Pon a prueba tus conocimientos sobre las 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 ven forzados a una relación de aspecto no natural, ¿qué estilos pueden ayudar a ajustar la forma en que la imagen se ajusta a estas proporciones?

object-fit
Especifica cómo la imagen se ajusta a 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 causar o resolver una relación de imagen no natural.

Si colocas height y width en tus imágenes, evitas que CSS pueda aplicarles un estilo diferente.

Verdadero
Piensa en ellos más como sugerencias que como reglas.
Falso
CSS tiene una gran cantidad de opciones dinámicas para cambiar 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, lo _______.

complementan, reemplazan
srcset definitivamente no reemplaza el atributo src.
reemplazar, complementa
Proporciona opciones adicionales para que el navegador elija, si es capaz.

Si falta alt en una imagen, es lo mismo que tener un alt vacío.

Verdadero
Un atributo alt vacío le indica a un lector de pantalla que esta imagen es de presentación.
Falso
Si falta alt, no se le indica nada al lector de pantalla.