El elemento picture y los formatos de respaldo
picture permite servir el formato más eficiente a cada navegador sin dejar a nadie sin imagen. Es la pieza clave para usar AVIF hoy con total seguridad.
Para qué sirve picture
<picture> envuelve un <img> y le añade una lista de fuentes alternativas. El navegador recorre los <source> en orden y usa el primero que cumpla las condiciones (tipo de archivo soportado y media query). Si ninguno encaja, usa el <img>.
Tiene dos usos principales:
- Cambio de formato: servir AVIF o WebP a quien los soporte y JPEG al resto.
- Dirección de arte: mostrar un recorte distinto según el tamaño de pantalla (por ejemplo, un encuadre vertical en móvil).
Cambio de formato
<picture>
<source type="image/avif" srcset="producto.avif">
<source type="image/webp" srcset="producto.webp">
<img src="producto.jpg" width="1200" height="1200" alt="Zapatilla de running azul vista de lado">
</picture>
Puntos importantes:
- El atributo
typees lo que permite al navegador descartar una fuente sin descargarla. Sin él, podría bajar un archivo que no sabe mostrar. - El orden va del formato más eficiente al más compatible.
- El
<img>final es obligatorio: es el que se muestra realmente y el que llevaalt,width,height,loadingyfetchpriority.
Un navegador que soporta AVIF descargará solo producto.avif. Nunca descarga varias fuentes para la misma imagen.
Estilos y atributos: siempre en el img
Un error frecuente es aplicar clases o atributos al <picture> o a los <source>. El <picture> no se renderiza como una caja propia en la mayoría de casos; quien ocupa espacio es el <img>. Por eso:
- Las clases CSS de tamaño,
object-fit, bordes, etc., van en el<img>. alt,width,height,loading,decodingyfetchpriorityvan en el<img>.- Los
<source>solo llevantype,srcset,sizesymedia.
Combinar formatos y tamaños
Cada <source> acepta srcset y sizes, así que puedes ofrecer varios anchos en cada formato:
<picture>
<source type="image/avif"
srcset="hero-960.avif 960w, hero-1920.avif 1920w"
sizes="100vw">
<source type="image/webp"
srcset="hero-960.webp 960w, hero-1920.webp 1920w"
sizes="100vw">
<img src="hero-1920.jpg"
srcset="hero-960.jpg 960w, hero-1920.jpg 1920w"
sizes="100vw"
width="1920" height="800" alt="…" fetchpriority="high">
</picture>
ImageZap genera exactamente este marcado: activa varios formatos y variantes responsive, abre Código en cualquier imagen y copia el resultado.
Dirección de arte con media
Si en móvil quieres un recorte diferente, usa media:
<picture>
<source media="(max-width: 640px)" srcset="banner-vertical.avif" type="image/avif">
<source media="(max-width: 640px)" srcset="banner-vertical.jpg">
<source srcset="banner-horizontal.avif" type="image/avif">
<img src="banner-horizontal.jpg" width="1600" height="600" alt="…">
</picture>
Ten en cuenta que, si las proporciones cambian, los atributos width y height del <img> solo describen la versión de escritorio. Los navegadores modernos permiten poner width y height también en cada <source> para reservar el espacio correcto en cada caso.
¿Y las imágenes de fondo CSS?
Para fondos, la función image-set() cumple el mismo papel:
.hero {
background-image: url("hero.jpg");
background-image: image-set(
url("hero.avif") type("image/avif"),
url("hero.webp") type("image/webp"),
url("hero.jpg") type("image/jpeg")
);
}
La primera declaración actúa como respaldo para navegadores que no entienden image-set() con type(). Recuerda que las imágenes de fondo se descubren tarde: si es la imagen LCP, añade un <link rel="preload">.
Preguntas frecuentes
¿Afecta picture al SEO?
No negativamente. Google indexa la imagen del <img> y también entiende las fuentes alternativas. El alt del <img> es lo que cuenta.
¿Puedo poner JPEG XL en picture?
Sí, como primera fuente. Safari lo usará y el resto de navegadores pasará a la siguiente. Asegúrate de incluir type="image/jxl".
¿Necesito picture si solo uso WebP?
Si tu público usa navegadores modernos, un <img src="foto.webp"> basta. picture es necesario cuando combinas formatos o haces dirección de arte.
¿Qué pasa con lazy loading?
Funciona igual: pon loading="lazy" en el <img> (salvo en la imagen principal).