Utilizando a tag “picture” do HTML5 com imagens responsivas

O tratamento de imagens responsivas hoje é sem dúvidas o assunto mais discutido na área de design para web. Neste artigo vamos ver como a tag <picture>, uma solução para imagens responsivas, pode ser utilizada no seu próximo projeto.

Este post faz parte do projeto que participo de tradução dos artigos dos blogs da Envato, Webdesigntuts+, Gamedevelopmenttuts+ e Nettuts+.

Link para artigo original: Quick Tip: How to Use HTML5 “picture” for Responsive Images
Autor do artigo original: Kezz Bracey
Link da envato para o artigo traduzido: Dica Rápida: Como Utilizar a tag “picture” do HTML5 Para Adaptar Imagens Responsivas

Primeiro, o problema

Os tempos de largura fixa e websites com design sólidos ficou para trás. Hoje temos que lidar com monitores widescreen, Smart TVs, tablets de diferentes tamanhos além de smartphones em uma escala de 320px até 768px (para mais, vide TVs e monitores 4K).

Junto a essa diversidade de resoluções de telas surge a necessidade de imagens que adaptam de acordo com os dispositivos. Isso prova ser um problema utilizar imagens, com exceção de vetores gráficos, pois a maioria das imagens tem tamanho fixo e não se adaptam a diferentes resoluções.

Então qual é a solução?

Até então, a solução mais comum

O exemplo abaixo é praticamente uma regra em qualquer website responsivo:

img {
    max-width: 100%;
    height: auto;
}

Esse código utiliza a propriedade max-width: 100%; para garantir que as imagens nunca ultrapassem a largura do elemento pai. Se o elemento pai mudar sua largura, a imagem vai manter a largura máxima dentro da largura limite apresentada pelo elemento acima. O código height: auto; garante a proporção da imagem nivelando a altura com base na largura.

Dica Rápida: Como Utilizar a tag "picture" do HTML5 Para Adaptar Imagens Responsivas - Web Social Dev
Uma imagem flexível para qualquer resolução

Isso resolve uma parte do problema, apresentando a mesma imagem para diferentes resoluções de tela. Mas não permite apontar diferente imagens para diferentes resoluções.

Uma nova solução: <picture>

<picture> é um novo elemento que está para ser introduzida ao HTML5

Esta tag permite tratar imagens responsivas da mesma forma que tratamos arquivos de áudio com a tag <audio> ou vídeos com a tag <video>. Também permite que você aponte várias imagens através da tag source.

Permite carregar diferentes arquivos de imagem através de:

  • Media Queries, para diferentes resoluções e orientações de tela
  • Densidade de pixels, para diferentes tipos de dispositivos

Isso quer dizer que você pode:

  • Carregar arquivos de tamanho específico, fazendo melhor uso da banda disponível com base no dispositivo utilizado.
  • Carregar diferentes imagens, com cortes específicos para cada resolução, o que evita perder a qualidade e o ponto ideal de exibição da imagem em diferentes dispositivos (o que pode inutilizar a imagem, vide posts do Facebook com imagens que excedem o tamanho proposto e são cortadas).
  • Carregue imagens com maior resolução para dispositivos com mais densidade de pixels.
Dica Rápida: Como Utilizar a tag "picture" do HTML5 Para Adaptar Imagens Responsivas - Web Social Dev
Diferentes imagens são disponibilizadas dependendo da resolução da tela/densidade de pixels

Como a tag <picture> funciona?

Os passos básicos para utilizar a tag <picture> são:

  1. Abrir e fechar a tag <picture></picture>.
  2. Dentro da tag <picture> crie a tag <source> para cada arquivo de imagem apontado.
  3. Adicione a tag media para atribuir Queries com base na resolução de tela, orientação da tela ou densidade de pixels.
  4. Adicione a tag srcset para atribuir o caminho dos múltiplos arquivos de imagem.
  5. Utilize o fallback com a tag <img> para navegadores que não suportarem o recurso.

Abaixo um exemplo básico que checa se o viewport é menor que 768px para então carregar uma imagem menor:

<picture>
    <source srcset="smaller.jpg" media="(max-width: 768px)">
    <source srcset="default.jpg">
    <img srcset="default.jpg" alt="My default image">
</picture>

Note que você pode utilizar a mesma sintaxe das Media Queries para CSS no atributo media, o que significa que você pode manipular os atributos max-width, min-width, max-height, min-height, orientation, entre outros.

Você pode utilizar o esquema abaixo para configurar que determinada imagem seja carregada de acordo com a orientação da tela e/ou em alguma das queries declaradas.

<picture>
    <source srcset="smaller_landscape.jpg" media="(max-width: 40em) and (orientation: landscape)">
    <source srcset="smaller_portrait.jpg" media="(max-width: 40em) and (orientation: portrait)">
    <source srcset="default_landscape.jpg" media="(min-width: 40em) and (orientation: landscape)">
    <source srcset="default_portrait.jpg" media="(min-width: 40em) and (orientation: portrait)">
    <img srcset="default_landscape.jpg" alt="My default image">
</picture>

O código acima carrega uma versão menor e cortada da imagem, para dispositivos em orientação landscape (deitado, normalmente tablets). Também carrega uma versão maior da imagem em dispositivos de telas maiores.

Se o dispositivo estiver na orientação portrait (em pé, normalmente smartphones), é carrega uma versão otimazada para a visualização em pé, também com o tamanho da imagem atrelado a resolução da tela.

Se você deseja executar os mesmas operações com base na densidade da tela utilizada, você precisa adicionar um parâmetro no atributo srcset. Por exemplo, vamos analisar um exemplo com foco em telas retina (2x a resolução comum):

<picture>
    <source srcset="smaller.jpg, smaller_retina.jpg 2x" media="(max-width: 768px)">
    <source srcset="default.jpg, default_retina.jpg 2x">
    <img srcset="default.jpg, default_retina.jpg 2x" alt="My default image">
</picture>

As Media Queries são carregadas primeiro, então você pode controlar o tamanho que a imagem vai ser apresentada na tela. Depois é checada a densidade de pixels da tela, se uma maior densidade for suportada, uma imagem de resolução superior é carregada.

Como utilizar a tag <picture>  agora mesmo:

Por enquanto o suporte nativo a tag <picture> ainda está em implementação no Chrome, Firefox e Opera. No futuro vamos ver disponíveis em qualquer dispositivos com suporte ao HTML5. Mas no momento ainda aguardamos o suporte nativo para utilizações sem ricos de compatibilidade.

Por outro lado, você não precisa esperara se quiser utilizar a tag <picture>. Você pode utilizar o Picturefill 2.0; um polyfill disponilizado pelo pessoa do Filament Group.

Dica Rápida: Como Utilizar a tag "picture" do HTML5 Para Adaptar Imagens Responsivas - Web Social Dev

Após efetuar download do picturefill.js e implementar ao seu projeto, carregue o arquivo na seção HEAD do seu documento HTML, como no exemplo abaixo:

<script src="picturefill.js"></script>

Você também tem a opção de carregar o picturefill em momentos específicos, para melhorar a eficiência, como conta na documentação do Picturefill.

Com o script carregado, o elemento <picture> deve funcionar como foi explicado, apenas com algumas limitações.

Limitações do Picturefill

IE9

O Picturefill opera muito bem com outras versões do IE, mas a versão IE9 não reconhece os elementos source presentes na tag picture. Para contornar a situção, utilizamos a tag video para apontar os sources e fazer com que os mesmos sejam reconhecidos no IE9, como no exemplo abaixo:

<picture>
    <!--[if IE 9]><video style="display: none;"><![endif]-->
    <source srcset="smaller.jpg" media="(max-width: 768px)">
    <source srcset="default.jpg">
    <!--[if IE 9]></video><![endif]-->
    <img srcset="default.jpg" alt="My default image">
</picture>

Android 2.3

O Android 2.3 apresenta o mesmo problema do IE9 no elemento source na tag picture. Por outro lado ele reconhece o atributo srcset quando utilizado com a tag img padrão. Garanta sempre um fallback através da tag img com o atributo srcset para o arquivo de imagem caso navegadores que apresentam esta falha.

Necessário suporte nativo a JavaScript e Media Queries

Sendo uma solução baseada em JavaScript, você precisa utilizar um navegador com suporte a linguagem, o que é comum (todos os navegadores recomendados hoje tem suporte a JS). O Picturefill 2.0 não oferece uma solução “no-js” porque várias imagens poderiam ser apresentadas quando o suporte a tag <picture> estiver disponível. De todo modo, se deseja utilizar uma solução “no-js”, você pode utilizara versão 1.2 do Picturefill.

A outra exigência do Picturefill é o suporte nativo a Media Queries, para habilitar o funcionamento do atributo media. Qualquer navegador moderno tem suporte a Media Queries, apenas o IE8 (que representam poucos usuários) para baixo não tem suporte a Media Queries.

Requisições HTTP extras

Em navegadores com suporte nativo ao srcset mas não a tag picture, é possível que o arquivo apontado no fallback seja requisitado antes de ser determinada a melhor imagem através do elemento source, no caso utilizando a tag picture.

Essa é uma falha temporária que vai ser solucionada quando o suporte nativo a tag picture estiver disponível.

Mais informações:

Teste assim que possível a tag <picture> nos seus projetos e veja o que acha deste novo recurso!