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.
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.
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.
Para evitar el aplastamiento y el estiramiento, usa la propiedad object-fit
.
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;
}
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.
img {
max-inline-size: 100%;
block-size: auto;
aspect-ratio: 2/1;
object-fit: cover;
object-position: top center;
}
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"
>
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"
>
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.
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.
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.
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
contain
y cover
.image-fit
fit-image
aspect-ratio
Si colocas height
y width
en tus imágenes, evitas que CSS pueda aplicarles un estilo diferente.
El atributo srcset
no _______ el atributo src
, lo _______.
srcset
definitivamente no reemplaza el atributo src
.Si falta alt
en una imagen, es lo mismo que tener un alt
vacío.
alt
vacío le indica a un lector de pantalla que esta imagen es de presentación.alt
, no se le indica nada al lector de pantalla.