Categorias
Projetos

Media queries e download de imagens

Como web design responsivo é uma área relativamente nova e, como você já deve saber, ainda nada pode ser considerado como “definitivo” ou “infalível”, é importante (e interessante e divertido) fazer vários testes para acompanhar a resposta dos navegadores em relação a este assunto.

E o que dizer sobre o carregamento de imagens no web design responsivo? Veja o resultado de alguns testes sobre como imagens são carregadas quando media queries fazem parte da brincadeira.

Media queries e download de imagens, teste 1: tag de imagem

O teste é relativo a tentar esconder uma imagem contida dentro de uma div usando display: none. O HTML e CSS são:

<div id="test1">
<img src="images/test1.png" alt="">
</div>
@media all and (max-width: 600px) {
#test1 { display: none; }
}

Resultados

Se há um método de esconder imagens que se pode dizer com 100% de certeza que deve ser evitado, é usar display: none. É completamente inútil. Parece que o Opera Mobile e Opera Mini não baixam a imagem, mas a imagem é solicitada por todos os outros.

TestadoImagem requisitada
Android 2.1+Sim
Blackberry (6.0+)Sim
Chrome (4.1+)Sim
Chrome MobileSim
Fennec (10.0+)Sim
Firefox (3.6+)Sim
IESim
iOS (4.26+)Sim
Kindle (3.0)Sim
Opera (11.6+)Sim
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
RockMeltSim
Safari (4+)Sim

Conclusão

Simplesmente não faça isso!

Media queries e download de imagens, teste 2: imagem de fundo e display: none

Nesse teste, numa div foi dada uma imagem de fundo. Com a viewport menor que 600px de largura, a div ficaria com display: none. O HTML e CSS:

<div id="test2"></div>
#test2 {
background-image: url('images/test2.png');
height: 75px;
width: 200px;
}
@media all and (max-width: 600px) {
#test2 { display: none; }
}

Resultados

Todos os navegadores testados, com exceção do Firefox, Opera Mini e Opera Mobile, baixam a imagem.

TestadoImagem requisitada
Android 2.1+Sim
Blackberry (6.0+)Sim
Chrome (4.1+)Sim
Chrome MobileSim
Fennec (10.0+)Sim
Firefox (3.6+)Não
IESim
iOS (4.26+)Sim
Kindle (3.0)Sim
Opera (11.6+)Sim
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
RockMeltSim
Safari (4+)Sim
SilkSim

Conclusão

Mais uma vez: não faça isso. Felizmente, como alguns dos outros testes mostram, existem algumas maneiras fáceis de esconder as imagens de fundo sem ter a imagem solicitada.

Media queries e download de imagens, teste 3: imagem de fundo, elemento-pai com display: none

Nesse teste, numa div foi dada uma imagem de fundo. O elemento-pai da div (outra div) foi setado com display: none quando a viewport tiver menos de 600px de largura. O HTML e CSS:

<div id="test3">
<div></div>
</div>
#test3 div {
background-image: url('images/test3.png');
height: 75px;
width: 200px;
}
@media all and (max-width: 600px) {
#test3 {
display: none;
}
}

Resultados

Num primeiro momento, não pareci claro porque essa método surtiria resultados diferentes dos testados anteriormente, mas, felizmente, ele se mostrou muito confiável.

TestadoImagem requisitada
Android 2.1+Não
Blackberry (6.0+)Não
Chrome (4.1+)Não
Chrome MobileNão
Fennec (10.0+)Sim
Firefox (3.6+)Não
IENão
iOS (4.26+)Não
Kindle (3.0)Não
Opera (11.6+)Não
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
Safari (4+)Não

Conclusão

Esse método funciona bem. Com exceção do Fennec, todos os navegadores testados apenas transferem a imagem quando necessário. O problema com este método é que você tem a necessidade de ser capaz de esconder o elemento contêiner. Se isso for possível, então sinta-se livre para ir em frente e usar essa abordagem.

Media queries e download de imagens, teste 4: imagem de fundo com sobrescrita em cascata

Nesse teste, numa div é dada uma imagem de fundo. Se a viewport for menor que 600px, então na div é dada uma imagem de fundo diferente. Isso foi testado para ver se ambas as imagens seriam solicitadas ou apenas a necessária. O HTML e CSS estão abaixo:

<div id="test4"></div>
#test4 {
background-image :url('images/test4-desktop.png');
height: 75px;
width: 200px;
}
@media all and (max-width: 600px) {
#test4 {
background-image: url('images/test4-mobile.png');
}
}

Resultados

Embora certamente melhor do que usar display: none, esse método é um pouco irregular.

TestadoImagem requisitada
Android 2.1-3.0?Sim
Android 4Não
Blackberry 6.0Sim
Blackberry 7.0Não
Chrome (16+)Não
Chrome MobileNão
Fennec (10.0+)Sim
Firefox (3.6+)Não
IE 9+Não
iOS (4.26+)Não
Kindle (3.0)Sim
Opera (11.6+)Não
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
RockMeltSim
Safari 4.0+Sim
Safari 5.0+Não

Conclusão

Preferível ser evitado. Embora a situação esteja melhorando, Android 2.x, que domina o marketshare do Android, ainda faz o download de ambas as imagens, assim como Fennec e Kindle. Entre os três, mas principalmente por causa do Android, é recomendado olhar para outras opções.

Media queries e download de imagens, teste 5: imagem de fundo com uso conjunto de min-width

Neste teste, é dada uma imagem de fundo para uma div se (min-width: 601px) acontece e uma imagem diferente para (max-width: 600px). O HTML e CSS são:

<div id="test5"></div>
@media all and (min-width: 601px) {
#test5 {
background-image: url('images/test5-desktop.png');
height: 75px;
width: 200px;
}
}
@media all and (max-width: 600px) {
#test5 {
background-image: url('images/test5-mobile.png');
height: 75px;
width: 200px;
}
}

Resultados

A situação já é um pouco melhor.

TestadoImagem requisitada
Android 2.1+Não
Blackberry (6.0+)Não
Chrome (16+)Não
Chrome MobileNão
Fennec (10.0+)Sim
Firefox (3.6+)Não
IE 9+Não
iOS (4.26+)Não
Kindle (3.0)Não
Opera (11.6+)Não
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
Safari (4+)Não

Conclusão

Mais navegadores se comportaram como o esperado dessa vez. Fennec, como sempre, ficou pra trás.

Também vale a pena usar esse método se você não precisa dar suporte para Internet Explorer 8 e versões anteriores. Essas versões do navegador não suportam media queries, de forma que nenhuma imagem será aplicada (claro, isso é bastante simples de se resolver com comentários condicionais e uma folha de estilos específica para IE).

Media queries e download de imagens, teste 6: imagem de fundo, display: none e (max-device-width)

Esse teste é igual ao teste 2, mas usar max-device-width ao invés de max-width. O HTML e CSS são:

<div id="test6"></div>
#test6 {
background-image:url('images/test6.png');
height: 75px;
width: 200px;
}
@media all and (max-device-width: 600px) {
#test6 {
display: none;
}
}

Conclusão

Não é preciso gastar muito tempo com isso, pois este acabou se mostrando um teste inútil. Não houve diferenças de comportamento entre ele e o teste 2.

Media queries e download de imagens, teste 7: sobrescrita em cascata para altas resoluções

O teste final foi adicionado ao conjunto um pouco tarde. Com a tela retina do iPad, fica fácil encontrar um monte de posts sobre como lidar com servir imagens para telas de alta resolução.

Nesse teste, numa div é dada uma imagem de fundo e, em seguida, usando a media query min-device-pixel-ratio, uma nova imagem de fundo é aplicada se o ratio mínimo for de 1,5.

HTML e CSS:

<div id="test7"></div>
#test7 {
background-image:url('images/test7-lowres.png');
height: 75px;
width: 200px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
#test7 {
background-image: url('images/test7-highres.png');
height: 75px;
width: 200px;
}
}

Resultados

De todos os testes, este é o único que pode beneficiar mais em ter mais pessoas o utilizando. Dito isso, parece que seu comportamento é acurado.

TestadoImagem requisitada
Android 2.1-3.0?Sim
Android 4Não
Blackberry 6.0Não
Blackberry 7.0Não
Chrome (16+)Não
Chrome MobileNão
Fennec (10.0+)Não
Firefox (3.6+)Não
IE 9+Não
iOS (4.26+)Não
Kindle (3.0)Não
Opera (11.6+)Não
Opera Mini (6.5+)Não
Opera Mobile (11.5)Não
Safari 4.0+Não

Conclusão

Infelizmente, parece que Android 2.x vai baixar as 2 imagens se o pixel ratio do dispositivo for superior ou igual a 1,5 (ou qualquer valor definido na media query). Assim, no caso dos testes acima, se você precisa suportar dispositivos de alta resolução com Android 2.x, você está sem sorte.

A boa notícia, por enquanto, é que não se sabe de qualquer dispositivo Android com pixel ratio maior que 1,5! Então, se você está mirando nos dispositivos iOS com Retina Display, você pode definir seu min-device-pixel-ratio em 2 com segurança.

Recomendações

Se você estiver indo pelo caminho de esconder uma imagem de conteúdo, você não poderá fazer isso definindo display: none. Para o caso, é recomendado usar JavasSript ou alguma abordagem server-side.

Se você quiser esconder uma imagem de background, a melhor aposta é a de esconder o elemento-pai. Se você não puder fazer isso, então use uma sobrescrita em cascata (como no teste 5) e defina background-image para none quando quiser ocultá-la.

Para trocar imagens de fundo, faça as devidas definições dentro de media queries.

PS: O repositório Media-Query-test no GitHub tem o código de todos os testes e é provável que seja atualizado mais frequentemente que este artigo.