<picture>
Imágenes y multimedia
Contenedor HTML para art direction de imágenes: permite servir fuentes distintas según el tamaño del viewport o el formato soportado, con un elemento <img> de fallback obligatorio.
<picture> es un elemento contenedor de HTML que permite ofrecer varias fuentes de imagen y dejar que el navegador elija la más adecuada para el contexto actual. Dentro de <picture> van uno o más elementos <source> — cada uno con sus condiciones — y un <img> de fallback obligatorio. El navegador recorre los <source> en orden, aplica el primer que coincide, y si ninguno coincide usa el <img>. La imagen que se muestra siempre es la del <img>; los <source> solo cambian el archivo que el navegador descarga.
El problema que <picture> resuelve es el art direction: servir versiones de imagen distintas (no solo de distinta resolución) según el viewport. Una imagen de producto puede mostrar el objeto completo en desktop, pero recortado en primer plano en mobile, donde el espacio es angosto y los detalles deben ser más grandes. Con srcset en un <img> solo se puede cambiar la resolución — el navegador elige cuál descargar, pero la imagen es la misma. Con <picture> se controla qué imagen va en cada contexto.
<picture> también es el mecanismo para servir formatos modernos (WebP, AVIF) con fallback a JPEG/PNG para navegadores que no los soportan: un <source type="image/avif"> seguido de <source type="image/webp"> y un <img src="foto.jpg"> garantiza que cada navegador recibe el mejor formato que puede manejar, sin JavaScript.
Cómo funciona
<picture> no dibuja nada por sí mismo — es un contenedor que le da al navegador un menú de opciones. El navegador evalúa cada <source> de arriba hacia abajo y usa el primero que cumple la condición. Si ninguno cumple, o si el navegador no soporta <picture>, usa el <img>.
<picture>
<source media="(min-width: 768px)" srcset="foto-ancha.jpg">
<source media="(min-width: 480px)" srcset="foto-media.jpg">
<img src="foto-angosta.jpg" alt="Paisaje de montaña">
</picture>
En este ejemplo: en viewports de 768px+ se carga foto-ancha.jpg; entre 480px y 767px se carga foto-media.jpg; en menos de 480px se carga el fallback foto-angosta.jpg.
Modelo de contenido
<picture> es un elemento contenedor — no es void y sí tiene contenido. Solo puede contener:
- Cero o más elementos
<source>(en cualquier orden, antes del<img>). - Exactamente un
<img>obligatorio, siempre al final.
No puede tener texto ni otros elementos. El <picture> en sí no genera ninguna caja visual — quien genera la caja es el <img> de dentro. El display, el tamaño y los estilos se aplican al <img>, no al <picture>.
En términos de contexto de uso, <picture> puede ir donde iría un <img> — dentro de <figure>, de un <a>, de cualquier contenedor que admita contenido de flujo o incrustado.
A nivel de accesibilidad, el rol implícito es el del <img> interior: los lectores de pantalla leen el alt del <img> como nombre accesible. El <picture> es transparente para la accesibilidad.
Sintaxis mínima
<picture>
<source media="(min-width: 768px)" srcset="imagen-desktop.jpg">
<img src="imagen-mobile.jpg" alt="Descripción de la imagen">
</picture>
Sub-elementos y atributos
<source> — las alternativas
Cada <source> es un candidato con sus condiciones. El navegador usa el primero que coincide. Sus atributos:
media
La condición de media query que debe cumplirse para que este <source> sea elegido. Sintaxis idéntica a las media queries de CSS, pero sin el @media:
<source media="(min-width: 768px)" srcset="foto-desktop.jpg">
Se evalúa exactamente igual que una media query de CSS. Si el viewport tiene 768px o más, este source se activa y el navegador descarga foto-desktop.jpg.
srcset
La URL de la imagen para este source. Puede incluir descriptores de densidad (1x, 2x) o descriptores de ancho (480w, 800w) para que el navegador elija la versión de mayor resolución según la pantalla:
<!-- Descriptores de densidad: para pantallas retina -->
<source media="(min-width: 768px)"
srcset="foto-desktop.jpg 1x, foto-desktop-2x.jpg 2x">
<!-- Descriptores de ancho: con sizes -->
<source media="(min-width: 768px)"
srcset="foto-800.jpg 800w, foto-1600.jpg 1600w"
sizes="(min-width: 1200px) 800px, 100vw">
sizes
Define qué tamaño visual ocupa la imagen en cada breakpoint, para que el navegador pueda elegir el descriptor de ancho correcto del srcset. Sin sizes, el navegador asume 100vw (ancho completo del viewport).
<source srcset="img-400.jpg 400w, img-800.jpg 800w, img-1200.jpg 1200w"
sizes="(min-width: 768px) 50vw, 100vw">
sizes="(min-width: 768px) 50vw, 100vw" significa: “en viewports de 768px+, la imagen ocupa el 50% del viewport; en menos, ocupa el 100%”. Con este dato, el navegador puede calcular cuántos píxeles reales necesita y elegir el candidato adecuado del srcset.
type
El tipo MIME del formato de imagen de este source. Permite servir formatos modernos con fallback:
<picture>
<source type="image/avif" srcset="foto.avif">
<source type="image/webp" srcset="foto.webp">
<img src="foto.jpg" alt="Descripción">
</picture>
El navegador usa el primer <source> cuyo type soporta. Si no soporta AVIF ni WebP, carga el foto.jpg del <img>.
<img> — el fallback obligatorio
El <img> al final del <picture> es obligatorio. Cumple dos roles:
- Fallback para navegadores sin soporte de
<picture>(o cuando ningún<source>coincide). - Receptor de atributos de presentación:
width,height,class,style,loading,decoding,fetchpriorityse ponen en el<img>, no en el<picture>.
<picture>
<source media="(min-width: 768px)" srcset="foto-desktop.jpg">
<img src="foto-mobile.jpg"
alt="Descripción de la imagen"
width="600"
height="400"
loading="lazy"
style="width:100%;height:auto">
</picture>
El alt vive en el <img>. Es el nombre accesible de la imagen — va siempre presente.
Ejemplo realista
Art direction para una imagen hero: plano completo en desktop, recorte centrado en mobile. Con soporte de WebP como bonus:
<picture>
<!-- Desktop: imagen panorámica, soporte WebP -->
<source media="(min-width: 768px)"
type="image/webp"
srcset="hero-wide.webp 1x, hero-wide-2x.webp 2x">
<source media="(min-width: 768px)"
srcset="hero-wide.jpg 1x, hero-wide-2x.jpg 2x">
<!-- Mobile: recorte cuadrado, soporte WebP -->
<source type="image/webp"
srcset="hero-square.webp 1x, hero-square-2x.webp 2x">
<!-- Fallback universal -->
<img src="hero-square.jpg"
alt="Montaña nevada al amanecer"
width="600"
height="600"
loading="eager">
</picture>
Cuándo usar <picture> vs. srcset en <img> solo
| Situación | Herramienta |
|---|---|
| Misma imagen, distintas resoluciones (retina vs normal) | srcset en <img> (1x/2x) |
| Misma imagen, distintos tamaños según viewport | srcset + sizes en <img> |
| Imágenes distintas según viewport (art direction) | <picture> con media en <source> |
| Formatos modernos con fallback (WebP, AVIF) | <picture> con type en <source> |
La regla práctica: si la imagen es la misma y solo cambia la resolución/tamaño, srcset en <img> es suficiente y más simple. Si la composición de la imagen debe cambiar según el contexto — un recorte distinto, una versión con texto vs sin texto, horizontal vs vertical —, <picture> es la herramienta.
Notas, gotchas e interacción
- El
<img>al final es obligatorio.<picture>sin<img>es un error: los navegadores sin soporte de<picture>ignoran el<picture>y sus<source>hijos, y buscan el<img>para mostrar algo. Sin<img>, no muestran nada. - Los estilos CSS van en el
<img>, no en el<picture>.max-width: 100%,display: block,border-radius— todos se aplican al<img>. El<picture>no genera caja visible. - El
altvive en el<img>. Es el nombre accesible de la imagen.<source>no tienealt. - El orden de los
<source>importa. El navegador usa el primero que coincide — ordená de más específico a menos específico. Un error común es poner el fallback mobile primero: el navegador lo usaría siempre. <picture>no funciona como lazyload automático.loading="lazy"se pone en el<img>, no en el<picture>. Aplica al recurso que finalmente se carga.- Cicatriz del sandbox (A.0.5): dentro del preview de este sitio, las imágenes deben ser SVG inline como data-URI. URLs externas no cargan en el sandbox.
Vigente / legacy
<picture> es vigente y Baseline widely. Antes de <picture>, la única opción nativa era srcset en <img> (sin art direction), o JavaScript para cargar imágenes distintas según el viewport. <picture> fue estandarizado junto con el srcset moderno en 2014–2016.
Aprendelo en el recorrido
Esta entrada complementa la lección Imágenes que no desbordan del módulo Diseño responsive.
Ver también
- img — el elemento imagen con
srcsetde densidad,max-width: 100%y atributos de rendimiento - responsive — diseño responsive: viewport, mobile-first y el toolkit
- media-queries — la misma sintaxis que usa el atributo
mediade<source> - width —
max-width: 100%para que el img nunca desborde su contenedor