Imágenes responsivas

El texto de la Web se ajusta automáticamente en el borde de la pantalla para que no se desborde. Es diferente con las imágenes. Las imágenes tienen un tamaño intrínseco. Si una imagen es más ancha que la pantalla, esta se desbordará y hará que aparezca una barra de desplazamiento horizontal.

Afortunadamente, puedes tomar medidas en los CSS para evitar que esto suceda.

Limita tus imágenes

En tu hoja de estilo, puedes declarar que las imágenes nunca se deben renderizar en un tamaño más ancho que el elemento que las contiene mediante max-inline-size.

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;
}

Cuando se implementa esa regla, los navegadores reducen automáticamente la escala de las imágenes para que quepan en la pantalla.

Dos capturas de pantalla; la primera muestra una imagen que se expande más allá del ancho del navegador; la segunda muestra la misma imagen restringida dentro de la vista del puerto del navegador.

Si agregas un valor block-size de auto, la relación de aspecto de las imágenes permanecerá constante.

A veces, las dimensiones de una imagen pueden estar fuera de tu control, por ejemplo, si la imagen se agrega a través de un sistema de administración de contenido. Si en tu diseño se requiere que una imagen tenga una relación de aspecto diferente a las dimensiones reales, usa la propiedad aspect-ratio en CSS.

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

Sin embargo, el navegador podría aplastar o estirar la imagen para que se ajuste a tu relación de aspecto preferida.

Perfil de un perro guapo y feliz con una pelota en la boca, pero la imagen está aplastada.

Para evitar que eso suceda, 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, incluso si eso implica dejar un espacio vacío arriba y abajo.

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, incluso si eso implica recortar la imagen en la parte inferior y superior.

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 guapo y feliz con una pelota en la boca; la imagen se recortó en la parte superior e inferior.
Se aplicó la misma imagen con dos valores diferentes para "object-fit". El primero tiene un valor de `object-fit` de `contain`. El segundo tiene un valor de `object-fit` de `cover`.

Si el problema es el recorte de las partes inferior y superior de manera uniforme, usa la propiedad de CSS object-position para ajustar el enfoque del recorte.

Navegadores compatibles

  • 32
  • 79
  • 36
  • 10

Origen

Puedes asegurarte de que el contenido de la imagen más importante siga estando visible.

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 feliz con una pelota en la boca; la imagen solo se recortó en la parte inferior.

Publica tus imágenes

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

Sugerencias de tallas

Si conoces las dimensiones de la imagen, debes incluir los atributos width y height. Incluso si la imagen se renderiza en un tamaño diferente (debido a tu regla max-inline-size: 100%), el navegador conoce la proporción entre el ancho y la altura y puede reservar la cantidad de espacio adecuada. De esta manera, evitarás que el resto del contenido salte cuando se cargue 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 una vez que se cargan las imágenes. En el segundo video, se proporcionaron las dimensiones de la imagen; queda espacio para la imagen, de modo que, una vez que se carguen, el texto no se salte.

Cargando sugerencias

Usa el atributo loading para indicar al navegador si debe retrasar la carga de la imagen hasta que se encuentre dentro del viewport o cerca del viewport. Para las imágenes en la mitad inferior de la página, usa un valor de lazy. El navegador no cargará 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"
>

En el caso de una imagen principal en la parte superior de la página, no se debe usar loading. Si tu sitio aplica automáticamente el atributo loading="lazy", a menudo puedes configurar el atributo eager (que es la opción predeterminada) para evitar que se aplique:

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

Prioridad de recuperación

Para imágenes importantes, como la imagen LCP, puedes priorizar aún más la carga con la prioridad de recuperación estableciendo 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 indicará al navegador que recupere la imagen de inmediato y con prioridad alta, en lugar de esperar hasta que el navegador haya completado el diseño cuando las imágenes normalmente se recuperan.

Pero recuerda que cuando le solicitas al navegador que priorice la descarga de un recurso, como una imagen, el navegador tendrá que 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 posible que algunas imágenes no estén disponibles en el código HTML inicial si las agrega JavaScript o como imagen de fondo en CSS. También puedes usar la precarga para permitir que estas imágenes importantes se recuperen con anticipación. Se puede combinar con el atributo fetchpriority para imágenes muy importantes:

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

Nuevamente, esto se debe usar con moderación para evitar anular demasiado la heurística de priorización del navegador, lo que puede disminuir el rendimiento.

La precarga de imágenes responsivas basadas en srcset (que se explica a continuación) mediante los atributos imagesrcset y imagesizes es más avanzada y es compatible con algunos navegadores, pero no con todos:

Mediante la exclusión del resguardo href, puedes garantizar que los navegadores que no lo admitan no carguen previamente la imagen incorrecta.

Por el momento, no se admite la precarga basada en diferentes formatos de imagen según la compatibilidad del navegador con esas imágenes y es posible que se generen descargas adicionales.

Lo ideal es evitar la precarga siempre que sea posible y tener la imagen disponible en el HTML inicial, para evitar la repetición de código y permitir el acceso a la gama completa de opciones que admite el navegador.

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. Luego, el navegador puede 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 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 cambiará la rapidez con la que se decodifica la imagen, sino solo el hecho de que el navegador espere a que se realice la decodificación de la imagen antes de renderizar otro contenido.

En la mayoría de los casos, esto tendrá poco impacto; sin embargo, en ciertas situaciones, puede permitir que la imagen o el contenido se muestren 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 un tiempo en decodificarse, configurar sync en imágenes importantes le indicará al navegador que espere por la imagen y renderice ambas a la vez. Como alternativa, configurar async puede permitir que el contenido se muestre más rápido sin esperar a que se decodifique la imagen.

Sin embargo, la mejor opción suele ser intentar evitar tamaños excesivos de DOM y garantizar que se usen imágenes responsivas para reducir el tiempo de decodificación, es decir, el atributo de decodificación tendrá poco efecto.

Imágenes responsivas con srcset

Gracias a esa declaración max-inline-size: 100%, tus imágenes nunca saldrán de sus contenedores. Pero incluso si parece bien tener una imagen grande que se reduce para ajustarse, no se sentirá bien. Si alguien usa un dispositivo de pantalla pequeña en una red con poco ancho de banda, descargará imágenes innecesariamente grandes.

Si creas varias versiones de la misma imagen en diferentes tamaños, puedes informar al navegador al respecto mediante el atributo srcset.

Descriptor de ancho

Puedes pasar una lista de valores separados por comas. Cada valor debe ser la URL de una imagen seguida de un espacio seguido de algunos metadatos sobre la imagen. Estos metadatos se denominan descriptores.

En este ejemplo, los metadatos describen el ancho de cada imagen con la unidad w. Un w es 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 no reemplaza al atributo src. En cambio, el atributo srcset complementa el atributo src. Aún debes tener un atributo src válido, pero ahora el navegador puede reemplazar su valor por una de las opciones que se enumeran en el atributo srcset.

El navegador no descargará las imágenes más grandes, a menos que sean necesarias. Eso ahorra ancho de banda.

Tamaños

Si usas el descriptor de ancho, también debes usar el atributo sizes para proporcionarle más información al navegador. Esto indica al navegador qué tamaño 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 indica al navegador que, por encima del ancho de un viewport de 66em, se debe mostrar la imagen con un ancho máximo de un tercio de la pantalla (por ejemplo, dentro de un diseño de tres columnas).

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

Para cualquier elemento inferior a 44em, muestra la imagen en todo el ancho de la pantalla.

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

Descriptor de densidad de píxeles

Hay otra situación en la que quizás quieras proporcionar varias versiones de la misma imagen.

Algunos dispositivos tienen pantallas de alta densidad. En una pantalla de doble densidad, puedes empaquetar dos píxeles de información en el espacio de un píxel. Esto mantiene las imágenes nítidas en ese tipo de pantallas.

Dos versiones de la misma imagen de un perro guapo y feliz con una pelota en la boca, una nítida y la otra borrosa.

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

<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 tiene un tamaño de 600 por 400 píxeles, medium-image.png puede tener 2x después de este en la lista srcset.

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

Imágenes de presentación

Las imágenes en HTML son contenido. Por eso, siempre proporcionas un atributo alt con una descripción de la imagen para los lectores de pantalla y los motores de búsqueda.

Si incorporas una imagen que es puramente un diseño visual sin contenido significativo, usa un atributo alt vacío.

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

Aún debes incluir el atributo alt. Un atributo alt faltante no es lo mismo que un atributo alt vacío. Un atributo alt vacío le indica al lector de pantalla que esta imagen es presentacional.

Idealmente, las imágenes decorativas o de presentación no deberían estar en tu HTML en absoluto. HTML es para la estructura. CSS es para 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 candidatas 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 elegirá la imagen más adecuada según la densidad de píxeles del dispositivo.

Hay muchos factores que debes considerar cuando agregas imágenes a un sitio:

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

Vale la pena invertir tiempo para obtener imágenes correctas. Las estrategias de mala calidad generan imágenes responsables de la frustración y la molestia de 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.

Hay un elemento HTML más en tu kit de herramientas que te ayudará a ejercer 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 el alto y el ancho de una imagen se ven forzados a una relación de aspecto poco natural, ¿qué estilos pueden ayudar a ajustar la forma en que la imagen se adapta a estas proporciones?

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

Si colocas height y width en tus imágenes, CSS no podrá asignarles un estilo diferente.

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 _______.

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

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

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