Imagens responsivas: Exemplos e códigos para iniciar seus estudos
Introdução
Finalmente a solução para servir imagens responsivas na web já é uma realidade. E mais, com uso de HTML puro sem necessidade de complicados hacks. O elemento picture
e os novos atributos para o elemento img
já são suportados no Chromium 37 com habilitação da respectiva flag (e em breve no Opera), no Firefox Nightly e está sendo implementado no WebKit embora ainda não haja informações se a Apple vai implementar suporte na próxima versão do Safari.
Suporte atual
Nota do Maujor: Transcreve-se a seguir a página do site caniuse.com que mostra o suporte desta funcionalidade nos navegadores atuais.
A sintaxe para o novo elemento picture
pode parecer verbosa e confusa, mas isso deve-se ao fato de ele elemento resolver uma gama variada de casos para servir imagens responsivas. Escrevemos essa matéria com a finalidade de mostrar a vocês a sintaxe para servir imagens responsivas em diversas situações, ilustrando cada caso com os respectivos códigos e exemplos.
Quatro perguntas
Antes de começar a usar imagens responsivas no seu projeto você deverá responder as quatro perguntas a seguir:
- As dimensões (sizes) da imagem variam em resposta às diferentes larguras de viewport?
- Serão servidas imagens otimizadas para telas de alta resolução (high-dpi)?
- Serão servidas imagens com diferentes tipo de mime (mime type) de acordo com o suporte oferecido pelo navegador?
- Será usada a técnica art direction para atender diferentes contextos de apresentação da imagem?
Nos exemplos que mostraremos a seguir vamos usar as palavras-chave sizes, dpi, mime e art, respectivamente para vincular o exemplo a cada uma das respostas ou combinação de respostas para as quais o exemplo se refere. Para cada exemplo faremos um breve comentário explicativo do código. Para criar os exemplos eu resolvi usar esta imagem noturna da sede do Opera em Oslo.
Lembre-se...
Antes de iniciar o estudo dos exemplos convém lembrar alguns conceitos conforme relacionados a seguir:
- O elemento último-filho do elemento
picture
deverá ser obrigatoriamente o elementoimg
. Se assim não for, nada será renderizado. Isso é muito bom para a acessibilidade, pois podemos usar o atributoalt
para fornecer uma alternativa textual para a imagem e ainda servir a imagem para navegadores antigos que não suportam o elementopicture
. - Pense no elemento
picture
e seus atributossizes
esrcset
como sendo os substitutos dos elementoimg
e seu atributosrc
. Use a propriedade JavasScriptcurrentSrc
para inspecionar qual é a escolha do navegador. Navegadores antigos escolhem o elementoimg
. - A lista de
srcset
esizes
presentes na sintaxe é uma dica para o navegqador e não um comando. Por exemplo um dispositivo com device-pixel-ratio igual a 1.5 é livre para escolher uma imagem que na sintaxe tenha sido declarada como 1x ou 2x, dependendo de suas capacidades, da conexão, etc. <img sizes="(max-width: 30em) 100vw …">
significa o seguinte: se a “media query” for verdadeira, mostre a imagem com largura igual a 100vw. A primeira “media query” verdadeira vence. Assim a ordem de declaração das “media queries” é importante.
Exemplo: art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1024px)"
srcset="opera-fullshot.jpg">
<img
src="opera-closeup.jpg" alt="The Oslo Opera House">
</picture>
Para larguras de janela iguais a 1024px CSS e maiores é servida a imagem em suas dimensões reais (fullshot) e para larguras menores serve-se uma parte da imagem (closeup).
Exemplo: tipo de mime
sizes dpi mime art
<picture>
<source
srcset="opera.webp"
type="image/webp">
<img
src="opera.jpg" alt="The Oslo Opera House">
</picture>
Navegadores que suportam o formato WebP servem a imagem neste formato, outros navegadores servem a imagem no formato JPG.
Exemplo: tipo de mime e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1024px)"
srcset="opera-fullshot.webp"
type="image/webp">
<source
media="(min-width: 1024px)"
srcset="opera-fullshot.jpg">
<source
srcset="opera-closeup.webp"
type="image/webp">
<img
src="opera-closeup.jpg" alt="The Oslo Opera House">
</picture>
Para larguras de janela iguais a 1024px CSS e maiores é servida a imagem em suas dimensões reais (fullshot) e para larguras menores serve-se uma parte da imagem (closeup). A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: High-DPI
sizes dpi mime art
<img
src="opera-1x.jpg" alt="The Oslo Opera House"
srcset="opera-2x.jpg 2x, opera-3x.jpg 3x">
Navegadores em dispositivos com tela de alta resolução recebem a imagem em alta resolução, outros navegadores recebem-na em resolução normal.
Exemplo: High-DPI e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1024px)"
srcset="opera-fullshot-1x.jpg 1x,
opera-fullshot-2x.jpg 2x,
opera-fullshot-3x.jpg 3x">
<img
src="opera-closeup-1x.jpg" alt="The Oslo Opera House"
srcset="opera-closeup-2x.jpg 2x,
opera-closeup-3x.jpg 3x">
</picture>
Para larguras de janela iguais a 1024px CSS e maiores é servida a imagem em suas dimensões reais (fullshot) e para larguras menores serve-se uma parte da imagem (closeup). A imagem será servida em sua versão alta resolução em navegadores instalados em dispositivos com tela em alta resolução e em resolução normal no demais navegadores.
Exemplo: High-DPI e tipo de mime
sizes dpi mime art
<picture>
<source
srcset="opera-1x.webp 1x,
opera-2x.webp 2x,
opera-3x.webp 3x"
type="image/webp">
<img
src="opera-1x.jpg" alt="The Oslo Opera House"
srcset="opera-2x.jpg 2x,
opera-3x.jpg 3x">
</picture>
Para navegadores em dispositivos com tela em alta resolução é servida a imagem com duas ou três vezes a quantidade de pixels da imagem normal, para outros navegadores é servida a imagem normal. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: High-DPI, tipo de mime e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1024px)"
srcset="opera-fullshot-1x.webp 1x,
opera-fullshot-2x.webp 2x,
opera-fullshot-3x.webp 3x"
type="image/webp"> <source
media="(min-width: 1024px)"
srcset="opera-fullshot-1x.jpg 1x,
opera-fullshot-2x.jpg 2x,
opera-fullshot-3x.jpg 3x">
<source
srcset="opera-closeup-1x.webp 1x,
opera-closeup-2x.webp 2x,
opera-closeup-3x.webp 3x"
type="image/webp">
<img
src="opera-closeup-1x.jpg" alt="The Oslo Opera House"
srcset="opera-closeup-2x.jpg 2x,
opera-closeup-3x.jpg 3x">
</picture>
Para larguras de janela iguais a 1024px CSS e maiores é servida a imagem em suas dimensões reais (fullshot) e para larguras menores serve-se uma parte da imagem (closeup). A imagem será servida em sua versão alta resolução em navegadores instalados em dispositivos com tela em alta resolução e em resolução normal no demais navegadores. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: sizes
sizes dpi mime art
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-200.jpg 200w,
opera-400.jpg 400w,
opera-800.jpg 800w,
opera-1200.jpg 1200w">
Para larguras de janela iguais a 640px CSS e maiores é servida uma imagem com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI.
Exemplo: sizes e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.jpg 200w,
opera-fullshot-400.jpg 400w,
opera-fullshot-800.jpg 800w,
press-fullshot-1200.jpg 1200w">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.jpg 200w,
opera-closeup-400.jpg 400w,
opera-closeup-800.jpg 800w,
opera-closeup-1200.jpg 1200w">
</picture>
Para larguras de janela iguais a 1280px CSS e maiores é servida a imagem em tamanho real com largura igual a 50% da largura da viewport, para larguras de janela entre 640-1279px CSS é servida a imagem com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI.
Exemplo: sizes e tipo de mime
sizes dpi mime art
<picture>
<source
srcset="opera-200.webp 200w,
opera-400.webp 400w,
opera-800.webp 800w,
opera-1200.webp 1200w"
type="image/webp">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-200.jpg 200w,
opera-400.jpg 400w,
opera-800.jpg 800w,
opera-1200.jpg 1200w">
</picture>
Para larguras de janela iguais a 640px CSS e maiores é servida a imagem em tamanho real com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: sizes, tipo de mime e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.webp 200w,
opera-fullshot-400.webp 400w,
opera-fullshot-800.webp 800w,
opera-fullshot-1200.webp 1200w"
type="image/webp">
<source
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.webp 200w,
opera-closeup-400.webp 400w,
opera-closeup-800.webp 800w,
opera-closeup-1200.webp 1200w"
type="image/webp">
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.jpg 200w,
opera-fullshot-400.jpg 400w,
opera-fullshot-800.jpg 800w,
opera-fullshot-1200.jpg 1200w">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.jpg 200w,
opera-closeup-400.jpg 400w,
opera-closeup-800.jpg 800w,
opera-closeup-1200.jpg 1200w">
</picture>
Para larguras de janela iguais a 1280px CSS e maiores é servida a imagem em tamanho real com largura igual a 50% da largura da viewport, para larguras de janela entre 640-1279px CSS é servida a imagem com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: sizes e high-DPI
sizes dpi mime art
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-200.jpg 200w,
opera-400.jpg 400w,
opera-800.jpg 800w,
opera-1200.jpg 1200w,
opera-1600.jpg 1600w,
opera-2000.jpg 2000w">
Para larguras de janela iguais a 640px CSS e maiores é servida a imagem em tamanho real com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI.
Exemplo: sizes, high-DPI e art direction
sizes dpi mime art
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.jpg 200w,
opera-fullshot-400.jpg 400w,
opera-fullshot-800.jpg 800w,
opera-fullshot-1200.jpg 1200w,
opera-fullshot-1600.jpg 1600w,
opera-fullshot-2000.jpg 2000w">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.jpg 200w,
opera-closeup-400.jpg 400w,
opera-closeup-800.jpg 800w,
opera-closeup-1200.jpg 1200w,
opera-closeup-1600.jpg 1600w,
opera-closeup-2000.jpg 2000w">
</picture>
Para larguras de janela iguais a 1280px CSS e maiores é servida a imagem em tamanho real com largura igual a 50% da largura da viewport, para larguras de janela entre 640-1279px CSS é servida a imagem com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI.
Exemplo: sizes, high-DPI e tipo de mime
sizes dpi mime art
<picture>
<source
srcset="opera-200.webp 200w,
opera-400.webp 400w,
opera-800.webp 800w,
opera-1200.webp 1200w,
opera-1600.webp 1600w,
opera-2000.webp 2000w"
type="image/webp">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-200.jpg 200w,
opera-400.jpg 400w,
opera-800.jpg 800w,
opera-1200.jpg 1200w,
opera-1600.jpg 1600w,
opera-2000.jpg 2000w">
</picture>
Para larguras de janela iguais a 640px CSS e maiores é servida a imagem em tamanho real com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Exemplo: sizes, high-DPI, tipo de mime e art direction use case
sizes dpi mime art
<picture>
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.webp 200w,
opera-fullshot-400.webp 400w,
opera-fullshot-800.webp 800w,
opera-fullshot-1200.webp 1200w,
opera-fullshot-1600.webp 1600w,
opera-fullshot-2000.webp 2000w"
type="image/webp">
<source
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.webp 200w,
opera-closeup-400.webp 400w,
opera-closeup-800.webp 800w,
opera-closeup-1200.webp 1200w,
opera-closeup-1600.webp 1600w,
opera-closeup-2000.webp 2000w"
type="image/webp">
<source
media="(min-width: 1280px)"
sizes="50vw"
srcset="opera-fullshot-200.jpg 200w,
opera-fullshot-400.jpg 400w,
opera-fullshot-800.jpg 800w,
opera-fullshot-1200.jpg 1200w,
opera-fullshot-1600.jpg 1800w,
opera-fullshot-2000.jpg 2000w">
<img
src="opera-fallback.jpg" alt="The Oslo Opera House"
sizes="(min-width: 640px) 60vw, 100vw"
srcset="opera-closeup-200.jpg 200w,
opera-closeup-400.jpg 400w,
opera-closeup-800.jpg 800w,
opera-closeup-1200.jpg 1200w,
opera-closeup-1600.jpg 1600w,
opera-closeup-2000.jpg 2000w">
</picture>
Para larguras de janela iguais a 1280px CSS e maiores é servida a imagem em tamanho real com largura igual a 50% da largura da viewport, para larguras de janela entre 640-1279px CSS é servida a imagem com largura igual a 60% da largura da viewport, para larguras menores é servida uma imagem com largura igual a largura da viewport. O navegador escolhe a imagem entre imagens com larguras iguais a 200px, 400px, 800px e 1200px, levando em conta a largura da imagem a servir e a resolução da tela em DPI. A imagem é servida no formato WebP para navegadores que suportam este formato, para outros navegadores a imagem é servida no formato JPG.
Mas, isso não é tudo!
Não se preocupe se você não entendeu o que acabou de ler. Em breve o autor publicará Yoav Weiss do Opera publicou um tutorial detalhado (em inglês) sobre o uso do elemento picture
para servir imagens responsivas. Por enquanto divirta-se preparando-se para impressionar seu chefe e seus clientes com a proposta de uma substantiva economia de banda e aumento de performance para seus projetos.
Conheça os livros do Maujor®
Ir para a página de entrada nos sites dos livros.