Picturefill e Imágenes Responsivas

PicturefillPicturefill es un polyfill, o sea, un archivo descargable de código que permite utilizar funcionalidades que aún no están integradas en un navegador. En otras palabras, Picturefill es un archivo (de javascript en este caso) que permite que los navegadores soporten al elemento <picture> y al atributo srcset con los que utilizamos técnicas para manejar imágenes en los sitios responsivos y evitar que éstos resulten ser inmensamente pesados.

Picturefill es desarrollado y mantenido por Filament Group y varias comunidades de desarrolladores; eso quiere decir que hay gente detrás de Picturefill que sigue probando y experimentando para encontrar una solución a las imágenes responsivas. El proyecto está abierto en Github, así que cualquiera puede involucrarse para seguirlo mejorando o proveer feedback.

Técnicas de imágenes responsivas

Las imágenes son el motivo principal por el cual un sitio responsivo se vuelve demasiado pesado. Con tantos dispositivos y pantallas de alta resolución, los diseñadores utilizan pesadas imágenes de alta calidad. Al hacer esto, sacrifican el performance afectando a muchos para el beneficio de unos pocos.

La única manera de evitar este problema consiste en preparar varias versiones de una imagen y hacer que el navegador descargue sólo la que sea más adecuada. Para lograr esto contamos con dos técnicas: usando el elemento <picture> y srcset y sizes.

El Elemento <picture>

<picture> es un contenedor de HTML que le provee a <img> de múltiples fuentes. Esto nos da la oportunidad de hacer que el navegador descargue la imagen más adecuada si las condiciones que le atribuimos se cumplen; por ejemplo: de acuerdo con el tamaño de la pantalla, el tamaño del viewport, resolución, etc.

Algo que debemos entender acerca de este elemento, es que no muestra nada por sí solo. Picture sólo provee un contexto para las imágenes que le insertamos y permite que los navegadores tomen una de las múltiples opciones.

Por ejemplo, en el siguiente markup se definen 3 pares de imágenes: Una para móvil, otra para tablet y otra para desktop. Cada una cuenta con su versión HD en caso de que se trate de una pantalla retina (2x).

<picture>
  <source sizes="200w" media="(min-width: 1024px)" srcset="http://natylove.com/wp-content/uploads/2015/06/pastel-desktop.jpg, http://natylove.com/wp-content/uploads/2015/06/pastel-desktop-hd.jpg 2x">
    <source media="(min-width: 680px)" srcset="http://natylove.com/wp-content/uploads/2015/06/pastel-tablet.jpg, http://natylove.com/wp-content/uploads/2015/06/pastel-tablet-hd.jpg 2x">
      <source srcset="natylove.com/wp-content/uploads/2015/06/pastel-movil.jpg, http://natylove.com/wp-content/uploads/2015/06/pastel-movil-hd.jpg 2x">
        <img src="http://natylove.com/wp-content/uploads/2015/06/pastel-movil.jpg" alt="Esta es la imagen de fallback">
</picture>

See the Pen GJvoZe by Natalia de la Selva (@NatyLove) on CodePen.

El resultado de este ejemplo está afectado por el viewport del iframe. Pero pueden ver el Pen en una ventana nueva, para que muestre las demás imágenes.

Podemos observar que dentro de <picture> hay 2 etiquetas:

  • <img>: Es el fallback. Si el navegador no soporta el elemento picture, entonces lo ignora y sólo muestra lo que hay en .
  • <source>: Source es donde vamos a especificar las diferentes imágenes; tiene cuatro atributos:
  • srcset: Aquí es donde colocamos la URL de cada imagen. Acepta múltiples URLs separadas con una coma, además, podemos emparejar las URLs con una resolución o ancho de pantalla:
srcset=“img-movil.png, img-movil-hd.png 2x”

Donde 2x significa una pantalla de doble densidad de pixels, o sea, de retina.

Si queremos emparejarla con un ancho, sería de la siguiente forma:

srcset=“img-movil.png 150w”
  • media: Permite especificar un media query el cual si, cuya condición se cumple, dará sugerencias sobre cuál de todas las imágenes de srcset debe descargar. Por ejemplo, si alguien está utilizando un iPhone 6 para ver nuestro sitio, descargará img-movil-hd.png.
  • sizes: Este atributo nos sirve para especificar el conjunto de tamaños intrínsecos de las fuentes descritas en srcset. También acepta múltiples valores separados por una coma.
  • type: Sirve para poner el tipo de las imágenes que estamos utilizando, si el navegador no soporta el formato, entonces se lo salta y pasa a la siguiente imagen.
    Type puede ser utilizado dentro de picture para utilizar formato de imagen que todavía no es bien soportado (por ejemplo webP) y dejar de fallback otra imagen que sí soporte (como un JPEG).
<picture>
  <source type="image/webp" srcset="images/mariposa.webp">
  <img src="images/mariposa.jpg" alt=“una mariposa">
</picture>
  • NOTA: El srcset y sizes de no deben confundirse con los que se utilizan en .

Srcset y Sizes

Al igual que <picture>, <img> también tiene el atributo srcset que puede utilizarse para definir varias fuentes (pero en esta caso van dentro de <img>) y pedirle al navegador que descargue la que considera más adecuada.

La manera de utilizar srcset en es igual que con . Sólo agregamos las URLs de las imágenes separadas por comas emparejadas con sus respectivos tamaños:

<img src="http://natylove.com/wp-content/uploads/2015/06/pastel-desktop.jpg" srcset="http://natylove.com/wp-content/uploads/2015/06/pastel-desktop.jpg 1200w, http://natylove.com/wp-content/uploads/2015/06/pastel-desktop-hd.jpg 2400w" alt="imágenes">

See the Pen MwvKjb by Natalia de la Selva (@NatyLove) on CodePen.

De esta manera, en vez de utilizar media queries, hacemos que el navegador tome el tamaño que le dijimos de antemano (por ejemplo 1000w) y lo divida entre la resolución y tamaño de la pantalla; eligiendo por sí mismo la imagen que considere más conveniente.

Picture vs Srcset y Sizes

Srcset y sizes es la técnica que probablemente vas a ocupar la mayor parte del tiempo. Su sintaxis no sólo es más sencilla que la de , sino que permite al navegador elegir por sí solo qué imagen utilizar. Lo cual es más conveniente porque está haciendo todo el trabajo matemático y puede tomar en cuenta más factores que los que nosotros podríamos conocer.

Si sólo quieres mostrar la misma imagen pero a diferente escala y resolución, srcset y sizes es la técnica más adecuada.

La misma imagen pero en diferentes resoluciones.
Srcset y Sizes si sólo necesitas escalar la imagen dependiendo del tamaño del viewport.

Utilizar <picture> requiere generar una gran cantidad de markup que en un futuro puede resultar difícil de mantener. Además con <picture> le estamos diciendo al navegador que elija la imagen que nosotros le especificamos ante ciertas condiciones (que por cierto, también especificamos). El problema con esto, es que hay factores que no podemos saber y que afectarán el contexto al que se vaya a enfrentar el navegador; así que no podemos asegurar que nuestra elección de imagen vaya a funcionar para todos los casos.

El elemento <picture> debe ser utilizado cuando un diseño responsivo pide una imagen diferente para diferentes tipos de pantalla, lo que lo hace perfecto para la dirección de arte. Por lo tanto, si necesitas modificar la imagen, como ajustar el encuadre y la proporción, entonces utiliza <picture>.

Dirección de Arte
Picture es la mejor opción cuando de trata de dirección de arte.

¿Cómo y para qué usar Picturefill?

Como se había establecido inicialmente, ambas técnicas de imágenes responsivas ocupan el uso de elementos que aún no han sido implementados por todos los navegadores. Con el apoyo de Picturefill, podemos utilizar y srcset y sizes en navegadores que todavía no soportan las tecnologías.

Para utilizar Picturefill sólo necesitas seguir los siguientes pasos:

    1. Descarga el archivo:
      • picturefill.js (versión de desarrollo, código sin minificar)
      • picturefill.min.js (versión de producción, código minificado)
      • Los links anteriores se refieren a la versión 2.3.1 que es la última más estable hasta el momento.
    2. Incluye el script en <head>:

Dentro de la sección <head> agrega el script de la siguiente forma:

<script src="picturefill.js"></script>
    1. Utiliza tu técnica de imágenes responsivas:

Ya puedes utilizar <picture> o srcset y sizes en el documento. Picturefill se encargará de que funcione en los demás navegadores.

Soporte y otras consideraciones:

  • Es importante visitar la página de Picturefill para obtener información útil que hay que tomar en cuenta si vamos a estar utilizando el polyfill con regularidad.
  • Picturefill por sí solo no es suficiente para soportar picture en IE9. Necesitas agregarle tags especiales al markup.
  • Los navegadores que no soportan picture mostrarán un alt si el javascript está desactivado.
  • Usuarios que tienen navegadores que soportan srcset pero no soportan <picture> pueden experimentar peticiones innecesarias al servidor.