Guía responsive image: Los atributos srcset y sizes y las bases de selección: art direction, dpi y tamaños 29.3.16
Responsive images: Una guía práctica para comprender y usar los distintos elementos y atributos que permiten utilizar imágenes "responsive" en la web actual y los atributos y valores para seleccionar en base a distintos criterios: art, dpi, tamaños...
Guía responsive image: Los atributos srcset y sizes y las bases de selección: art direction, dpi y tamaños
El elemento picture
y su hijo asociado source
junto a los atributos srcset
, sizes
, definidos originalmente para el elemento img
, es la respuesta actual vencedora en la batalla para dotar al desarrollador de herramientas para el manejo de las imágenes en el escenario del responsive web design
.
Así, con un uso correcto de estos elementos y atributos, ya es posible disponer de responsive images
: servir el archivo de imagen que mejor se adapta al dispositivo que recibe la página.
El elemento picture
Del elemento picture
dice la especificación que es un contenedor que provee múltiples orígenes para la imagen contenida en él. Lo que permite a los desarrolladores controlar o sugerir al navegador qué imagen mostrar.
El elemento picture
debe tener dos hijos:
- Un elemento
source
como mínimo - Un elemento
img
obligatorio
<picture>
<source srcset='set de imágenes' />
<img src='...' alt='descripción' />
</picture>
El valor del atributo srcset
es una ruta a un recurso de imagen o un grupo de rutas separadas por comas. Cada valor de ruta y separado por un espacio en blanco puede ir acompañado de algún tipo de información o pista para que el navegador seleccione la que mostrar en base al tamaño del viewport o la densidad del dispositivo.
El elemento img
es requerido
. Esto es, si no se incluye no se mostrará ninguna imagen. Su ausencia convierte al elemento picture
en un elemento vacío.
El elemento source
contiene los grupos de imágenes entre los que se elegirá la que mostrar. Un mismo picture
puede contener tantos elementos source
como se necesiten.
El atributo srcset
también puede ser utilizado en los elementos img
(también si img es hijo de un picture
). En cuyo caso es obligado incluir además del srcset
el atributo src
:
<img
srcset='set de imágenes'
src='valor.ext'
Otros atributos />
Criterios de selección de la imagen
Bien, gracias al elemento source
indicamos al navegador el paquete de imágenes disponibles para elegir una de entre todas. Pero por sí mismo poco o ningún control hay sobre la imagen final mostrada.
En estos momentos, hay cuatro criterios de selección que se identifican con cuatro palabras claves (o keywords): size, dpi, mime y art en base a ellos, el desarrollador puede sugerirle al navegador qué imagen mostrar.
- size
- Por tamaño del viewport
- dpi
- por densidad de píxeles del dispositivo
- mime
- por tipo del archivo de imagen (extensión)
- art
- por criterios artísticos en función de la imagen y contextos de presentación
Ahora la cuestión es ¿cómo indicarle ésto al navegador? Y la respuesta es sencilla: mediante los distintos atributos disponibles para ello: sizes, media, type (son opcionales) junto al ya indicado srcset.
Estos criterios se pueden usar individualmente o de forma conjunta varios de ellos.
Selección por densidad de píxeles: DPI
Para comenzar, un caso sencillo. Tengamos el siguiente código. Uso el elemento img
para hacer más sencillo el código. Pero es igual si el elemento utilizado fuese un picture
.
<img
srcset='imagen-1x.jpg, imagen-2x.jpg 2x, imagen-4x.jpg 4x'
src='imagen.jpg'
alt='texto alternativo' />
En el valor del atributo srcset
se indican las rutas a tres imágenes. A continuación cada ruta (separado por un espacio en blanco y antes de la coma que las separa) se indica un valor Nx
que es la referencia para que el navegador seleccione la que mejor se ajuste a la densidad de píxeles (DPI) del dispositivo que la mostrará.
Observa que la primera carece de este valor (Nx
) porque por defecto o en su ausencia el valor es 1x
.
En este caso, los distintos archivos de imagen pueden ofrecer o no la misma visión. Lo que sí es que cada archivo está guardado en una resolución diferente.
Selección por tamaño: atributo sizes
Para mostrar imágenes en función del tamaño de la pantalla o ventana se utiliza el atributo sizes=''
. Admite un valor sizes='100vw'
o múltiples valores separados por comas.
Los valores admitidos como válidos son cualquiera de los usados en tamaños (px, rem, unidades relativas al viewport) e incluso @medias queries: sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
En este último código de ejemplo el valor que precede a la coma indica la superficie que cubrirá la imagen en cada tamaño de ventana. El último es el usado como valor por defecto.
<img
sizes="(min-width: 800px) 60vw, 100vw"
srcset="imagen-1.jpg 200w,
imagen-2.jpg 400w,
imagen-3.jpg 800w,
imagen-4.jpg 1200w"
src="img-X.jpg" alt="texto alternativo" />
Con este código, en ventanas de 800px o mayores la imagen se muestra ocupando el 60% de la anchura de la ventana y en menores el 100%. Y en base a ello el navegador mostrará una de las imágenes indicadas en el srcset
en función del tamaño de la ventana y de la densidad de píxeles de la pantalla.
También se puede indicar archivo de imagen por tamaño de ventana de la siguiente forma con el elemento source
y el atributo media
:
<picture>
<source media='(min-width: 45rem)' srcset='large.jpg'>
<source media='(min-width: 18rem)' srcset='medium.jpg'>
<img src='small.jpg' alt='texto alternativo' />
</picture>
Por formato de archivo
En caso de querer ofrecer diferentes tipos (extensión) de archivo de imagen, el atributo a utilizar es type
.
<picture>
<source
type="image/webp"
srcset="imagen.webp">
<img src="imagen.jpg" alt="texto alternativo" >
</picture>
Los navegadores que soporten el formato webp
mostrarán dicho archivo, el resto el jpg.
Por criterios artísticos: art direction
Debido a la disparidad que hay en la relación de aspectos de pantallas, hay imágenes que por su composición artístisca
perderían la información relevante si sólo se escalasen en su tamaño para ajustarse al tamaño de las pantallas o su densidad de px. Como en la imagen de abajo.
Sin embargo, utlizando criterios artísticos en vez de basarnos en el tamaño del viewport el resultado será mucho más satisfactorio:
Tengamos dos recortes distintos de una fotografía, uno en vertical y otro en horizontal, para ser mostrado en función de la orientación del dispositivo (landscape o portrait):
<picture>
<source media="(orientation: landscape)" srcset="art-landscape.jpg">
<source media="(orientation: portrait)" srcset="art-portrait.jpg">
<img src="art-direction-no.jpg" alt="texto alternativo">
</picture>
Recuerda que como valor del atributo media
se puede utilizar cualquiera de los admitidos por las @medias queries
de Css.
Picture por múltiples criterios
Lo que suele ocurrir en la realidad es que las cosas suelen ser más complejas. Así que lo más fácil que te puede ocurrir es que el código final a utilizar en cada caso sea función de las características de cada imagen más aquellos escenarios que necesites o desees cubrir.
Será común que tengas un set de archivos de la misma imagen a distintos tamaños y/o resoluciones y a la vez distintos recortes de ella también en distintos tamaños y resoluciones.
No será extraño, pues, que necesites combinar dos o más criterios: art direction + size + dpi, por ejemplo:
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="imagen-completa-200.jpg 200w,
imagen-completa-400.jpg 400w,
imagen-completa-800.jpg 800w,
imagen-completa-1200.jpg 1200w,
imagen-completa-1600.jpg 1600w,
imagen-completa-2000.jpg 2000w" >
<img
sizes="(min-width: 640px) 60vw, 100vw"
srcset="imagen-recorte-200.jpg 200w,
imagen-recorte-400.jpg 400w,
imagen-recorte-800.jpg 800w,
imagen-recorte-1200.jpg 1200w,
imagen-recorte-1600.jpg 1600w,
imagen-recorte-2000.jpg 2000w"
src="imagen-recorte-400.jpg" alt="texto alternativo" />
</picture>
En viewports de anchura 1280 píxeles CSS o más, se muestra una imagen completa ocupando un 50% del ancho de la ventana utilizada; para las ventanas del navegador con una anchura de 640-1279 píxeles CSS, la imagen ocupa un 60% del ancho de la ventana; por ventanas del navegador menores a 640px, se usa una foto con una anchura que es igual a la anchura de la ventana gráfica completa.
En cada caso anterior, el navegador mostrará una de las imágenes opcionales indicadas en el atributo srcset
(cada una de ellas con un ancho de 200px, 400px, 800px, 1200px, 1600px 2000px) teniendo en cuenta el ancho de la imagen y la densidad de la pantalla (DPI).
La anchura le es sugerida al navegador con el valor numérico terminado con w
que acompaña a cada valor o ruta del srcset separado por un espacio en blanco.
En la siguiente demo podrás ver el cambio de imagen según sea la orientación y tamaño de la ventana porque cambia el valor de la cantidad (dimensiones de la imagen) que hay impreso en cada imagen.
En caso contrario te aparecerá el valor del atributo alt
del elemento img
del picture
pues la ruta de la imagen no apunta a ninguna.
See the Pen Picture element: by orientation & sizes of viewport by Kseso (@Kseso) on CodePen.
Lecturas complementarias y soporte
Sí. Esta solución y recurso para lidiar con imágenes responsives
es a la vez potente, versátil y compleja. Y el mejor código (por efectivo y útil) dependerá de cada situación en concreto: tipo de imagen y situaciones a contemplar.
Para dominarlo, nada mejor que escribir código y ver resultados. Pero hoy por hoy no en todos los navegadores verás el funcionamiento tanto del elemento picture
y sus hijos asociados así como de los atributos implicados. Y visto el ritmo con el que los equipos de desarrollo sacan versiones nuevas, lo mejor es que en cada momento consultes su soporte:
Consulta soporte
Funcional, para mi y en el momento de escribir el artículo, en Chrome estable y Chrome Canary últimas versiones en windows.
Firefox en su versión 35+ también le da soporte. Pero con una particularidad: una vez cargada la imagen correspondiente no realiza cambios en ella al variar las condiciones del viewport.
Otras lecturas
- Picture, srcset y demás elementos y atributos en HTML 5.1 Nightly
- Responsive Images: Use Cases and Documented Code Snippets
- Native Responsive Images
- Built-in Browser Support for Responsive Images
- Guía: Images in Markup
- Responsive Images: The Ultimate Guide
Artículo publicado originalmente en Octubre de 2014. Artículo liberado y marcado como postcrossing.
Kseso
the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso
Queda claro como el agua. Así da gusto leer y aprender. Lo único malo es el escaso soporte. Firefox da soporte si lo activas así que no creo que tarde mucho en venir "de serie" (o espero). Y en cuanto a Safari ¿no es extraño que chrome y opera lo soporten y el de Apple no? Hacen cosas muy raras estos de Apple.
ResponderEliminarPd. El último enlace que va a codepen ("Ver Demo a Full") ha perdido el href y no lleva a ninguna parte. No es mucho problema porque se puede ver desde el enlace "Edit on Codepen" pero bueno.... Por si llega algún novato como yo lo tiene más fácil.
Gracias, Jaime
EliminarMe alegra que lo encuentres útil.
Un saludo.
P.D.: corregido el enlace :palm:
Muy bueno, de veras q da gusto leerlo, solo una duda aqui:
ResponderEliminar"el navegador mostrará una de las imágenes opcionales indicadas en el atributo srcset (cada una de ellas con un ancho de 200px, 400px, 800px, 1200px, 1600px 2000px) teniendo en cuenta el ancho de la imagen y la densidad de la pantalla (DPI)."
supongo q ponga la img imagen-recorte-200.jpg en resoluciones de 200 a 399, imagen-recorte-400.jpg en resoluciones de 400 a 799, y asi ..., cada una con el ancho correspondiente mencionado, corrigeme si estoy mal. Cuando dices "teniendo en cuenta el ancho de la imagen y la densidad de la pantalla (DPI)" es q se hace algun calculo en especifico ? porfa si pudieras aclararme como es q se hace esa seleccion te lo agradeceria.
En ese código de ejemplo sólo se tiene en cuenta el tamaño del viewport a la hora de indicar las preferencias sobre qué imagen usar (tamaños y superficie a cubrir).
EliminarComo no se han contemplado otros criterios (como la densidad de px del dispositivo) en un momento dado el navegador (en función de su programación interna) puede optar por mostrar una imagen mayor a la que le correspondería por tamaño del viewport en función de la densidad de píxeles del dispositivo que recibe la página.
Un poco viejo este post, Imágenes para dispositivos de alta densidad. La técnica 2*0.4 al 50%, pero quizás te ayude a comprenderlo.
Un saludo
Que gran explicación, excelente todo muy bien, los ejemplos las técnicas, ojala todo fuera tan claro como este gran articulo
ResponderEliminarMuchas Gracia por compartirlo
Mi pregunta es cual seria el tamaño y la resolución de una imagen que sera linkeado a una pagina web para que se pueda ver desde un viejo Nokia con Android hasta un smartTv de 45 pulgada o mas; soy un aprendiz en esto de crear paginas web ya que lo hago porque un amigo me pidió que le hiciera una pagina web, él no es bueno con la computación.
ResponderEliminarNo la hay, Mario.
EliminarY por eso todo lo que se ha escrito y se escribirá sobre las "responsive images".
Un saludo.