Como tratar das imagens em seu site visando atender diferentes tamanhos e resoluções de tela?

A melhor imagem para as caracteristicas de tela do dispositivo.

Hoje dispositivos com os mais diversos tamanhos e resoluções de telas acessam a internet.

Naturalmente, queremos que nosso site apresente-se da melhor maneira possível nessa grande variedade de telas, e as imagens são parte importante para o atingimento desse objetivo.

Ao desenvolver nossas páginas, procuramos usar o mínimo possível de medidas fixas (como o pixel) justamente porque estamos lidando com todo tipo de tela, com tamanhos e resoluções diversas. Portanto, usa-se medidas relativas, como a porcentagem, por exemplo.

Todavia, se tratando de imagens, não tem muito como escapar. Visto que, elas são pixels.

É claro que temos a opção de utilizar Gráficos Vetoriais Escalonáveis, que são os Scalable Vector Graphics SVGs e Icon Fonts. Aliás, use-os sempre que puder. Eles têm um tamanho pequeno e se adaptam bem, estão prontos para serem utilizados em todo tipo de tela, já que podem ser dimensionados para o tamanho que você quiser, sem perder definição. São ótimos para gráficos simples, padrões, elementos de interface, etc.

Mas começa a ficar complexo criar uma imagem baseada em vetor com o tipo de detalhe que você encontraria em uma foto, por exemplo. Formatos de imagens rasterizadas, como JPEGs, são melhores para isso.

Quanto maior o tamanho ou qualidade de uma imagem rasterizada, mais pesado tende a ficar seu arquivo.

Carregar uma imagem muito grande em cenários onde o acesso está sendo feito em uma tela pequena ou uma imagem HD em uma tela de resolução baixa, são dois exemplos de desperdício de largura de banda.

Usuários mobile – especialmente – não querem ter que gastar seu pacote de dados baixando uma imagem grande feita para Desktop, quando uma imagem pequena poderia ser feita para seu dispositivo. É por isso que imagens otimizadas também impactam positivamente no ranking de seu site nos mecanismos de busca.

Uma solução possível, seria ter múltiplas resoluções disponíveis e apresentar tamanhos apropriados de imagens, dependendo das características de tela do dispositivo que estiver fazendo o acesso.

Carregar Imagens de Acordo com a Resolução de Tela do dispositivo do Usuário

Por que a resolução de tela deve ser levada em consideração na escolha da imagem?

A resolução pode ser entendida como a densidade de pixels presentes na tela. A densidade, refere-se à quantidade de pixels apertados em um espaço físico normalmente, uma polegada. Sendo representada muitas vezes pela sigla PPI (pixels per inch, pixels por polegada). Fazendo uma analogia, seria algo como população por metro quadrado. Já o pixel, em uma linguagem mais coloquial, é o menor quadradinho físico em sua tela, e que recebe uma cor.

As telas sempre evoluíram, em toda a história da computação. Mas um novo capítulo dessa evolução começou a ser escrito no ano de 2010, quando a Apple lançou o seu iPhone 4 com uma tela de altíssima resolução, chamada por eles de Retina.

Retina é um termo criado pela Apple, para denominar telas que tenham uma densidade de pixels tão alta, que um ser humano com visão normal não consegue detectar pixels individuais a uma distância apropriada de visualização.

Existe uma distância recomendada entre o olho e a tela para cada dispositivo. No celular, por exemplo, ela é algo em torno de 30 centímetros, no computador, 40. Portanto, toda tela que se encaixe no conceito, pode ser chamada de Retina.

Como a evolução das telas tem levado essa densidade para níveis muito altos, temos cada vez mais pixels espremidos em uma polegada. Obviamente, para caber mais pixels em um mesmo espaço físico, os pixels precisam ficar menores.

Telas com diferentes tamanhos de pixels físicos, geram o tipo de problema que estamos tentando descrever abaixo.

Temos inicialmente uma tela, onde renderizamos um objeto que ocupou 24 pixels.

Pixels in a display.

Como a próxima tela tem o dobro da resolução, o tamanho físico dos pixels caiu pela metade.

Pixels in a retina display.

Se o tamanho dos pixels reduziu pela metade, ao renderizar a imagem nos mesmos 24 pixels, o objeto fica visualmente menor.

Como no mercado existem inúmeras resoluções de tela, para corrigir essas diferenças de apresentação, criou-se então um pixel referência, onde não necessariamente uma medida desse pixel corresponde a exatamente um pixel físico.

Essa medida recebe vários nomes: Device Independent Pixel na documentação do Android; na W3C, é chamada de CSS Pixel, e na Apple, de Dots. Outro nome também encontrado em documentações, é Pixel Lógico.

Isso permite aos dispositivos, baseados em sua densidade, definir quantos pixels físicos realmente corresponderão a um pixel lógico, garantindo uma renderização padronizada em todas as resoluções. O que é bom, pois abstrai essa responsabilidade de nós, desenvolvedores.

A divisão entre a quantidade de pixels físicos pela de pixels lógicos de uma tela, gera uma nova métrica: o Device Pixel Ratio – DPR.

Essa conta não é feita na mão, mas em algumas situações, precisamos do DPR para tomar decisões sobre nossas imagens. Informação que pode ser obtida com JavaScript, através da propriedade devicePixelRatio, ou acessada pelo CSS, conforme veremos no decorrer do artigo.

Device Pixel Ratio.

DPR de 1, significa dizer que um pixel lógico corresponderá a um pixel físico. Já se a proporção for 2, por exemplo, um pixel lógico será desenhado utilizando-se o dobro de pixels físicos.

Quando tratamos de elementos vetoriais como textos e SVGs, tanto faz quantos pixels físicos serão realmente utilizados para desenhar cada elemento. Desde que a proporção seja mantida, está tudo certo.

Mas, ao lidar com imagens rasterizadas, as coisas não são bem assim. Esse tipo de imagem possui um número de pixels de largura e um número de pixels de altura, e começa a parecer granulada, quando forçada a se desenhar em uma quantidade maior de pixels do que a de seu tamanho original.

Em nosso exemplo acima, vamos assumir que a primeira tela tenha um DPR de 1 e a segunda, um DPR de 2. Para que o objeto desenhado na primeira tela permaneça com o mesmo tamanho visual na segunda, ele ocupará 4 vezes mais pixels.

Isso quer dizer que: se o objeto ocupou 24 pixels na primeira tela, será forçado a se renderizar em 96 pixels na segunda. Aí não tem mágica, cada um dos 24 pixels existentes originalmente na imagem, será esticado para o dobro de seu tamanho. Fazendo com que a imagem pareça embaçada, pois não há dados suficientes para que ela seja exibida corretamente. É daí que vem o termo, encontrado em artigos falando sobre o assunto, de que a tela retina explode o pixel.

Portanto, existe apenas uma solução para esse caso: dobrar o tamanho da imagem.

Para implementar essa ideia, poderíamos continuar disponibilizando nossas imagens originais em dispositivos com telas normais, de 1 DPR por exemplo, e gerar uma nova imagem, com o dobro das dimensões, para telas 2 DPRs e maiores.

Inserindo as Imagens via CSS

Quando você deseja inserir uma imagem somente decorativa em seu site, é aconselhável que o faça via CSS, para não poluir o HTML com elementos que só estariam ali por questões visuais.

Então para telas comuns, simplesmente importamos nossa imagem original, que poderia ser algo como o mostrado na tira de código abaixo.


  .site-panorama {
      background-image: url(imagens/panorama.jpg);
  }

E para telas Retina, envolvemos o CSS que importa nossa imagem @2x em uma media query min-resolution, com o valor 2dppx. O código dentro da media query só será executado para situações onde o DPR for 2 ou maior.


  @media (min-resolution: 2dppx) {
      .site-panorama {
          background-image: url(imagens/panorama@2x.jpg);
      }
  }

Dessa forma, nossa imagem@2x só será carregada para telas retina. Aliás, essa forma de nomear imagens, colocando o arroba seguido do DPR surgiu na Apple, e hoje é bastante comum de se encontrar em diversos sites por aí. Ela ajuda a organizar melhor nossas imagens, identificando suas finalidades.

O fato de você ter dobrado as dimensões de sua imagem, não quer dizer que ela vai se renderizar com a metade do tamanho em telas retina, ficando do mesmo tamanho da imagem original numa tela 1x. Ela agora terá o dobro do tamanho visual em qualquer tela, por conta da história do pixel referência visto acima.

Você precisa forçar que ela se renderize com a metade do tamanho. Por que aí, em vez de o sistema operacional do dispositivo com tela retina esticar os pixels, simplesmente todos eles serão ocupados.

Uma forma, é colocar o background size com o tamanho do arquivo.

background-size: 500px 500px;

Inserindo as Imagens Através do HTML

Nos casos em que a imagem realmente é parte do conteúdo, e você deseja adicioná-la pela tag img, há algumas possibilidades.

O srcset surgiu como um novo atributo na tag img, sendo uma ferramenta a mais disponível para se trabalhar com web design responsivo em diferentes tamanhos e resoluções de tela. Ele nos permite trocar o src da imagem, e assim, carregar uma imagem específica de acordo com as características da tela do dispositivo.

Informamos no srcset uma lista separada por vírgula, contendo o caminho da imagem e a resolução na qual deve ser apresentada.

No entanto, você não deve esquecer de fornecer o atributo src, como já se fazia antigamente. Assim, os navegadores que não suportam srcset também receberão uma imagem.

Tag img com atributo srcset.

Com o srcset, não precisamos dimensionar a imagem. Isso já é feito automaticamente, através da informação de resolução da imagem, aquele 1x, 2x após o caminho. Fazendo com que ela tenha sempre o mesmo tamanho.

Como no mercado existem telas das mais variadas resoluções, num cenário onde eu tenha como opções em um srcset, preparada uma imagem 1x e outra 2x, quando um dispositivo com DPR de 1.5 fizer o acesso, será servido com a imagem 2x. Da mesma forma, considerando ainda essas duas opções de imagens, um dispositivo com DPR 3, receberá a imagem 2x.

Decidir pela melhor imagem considerando o tamanho de tela do dispositivo

Carregar determinada imagem, dependendo do tamanho de tela do dispositivo, é chamado pelo mercado de direção de arte. Afinal, é o caso de o diretor artístico do site definir qual recorte, por exemplo de uma imagem, se encaixa melhor para aquelas dimensões de tela.

O elemento picture, que surgiu recentemente, foi pensado justamente para esses casos. Dentro dele, colocamos uma lista de sources. Cada um composto por um conjunto de regras, e o endereço de uma imagem informada no atributo src.

A imagem do source em que as regras combinarem com as especificações da tela do dispositivo, será carregada e exibida na página.

Adiciona-se também dentro de picture, uma tag img. É nela que colocamos a descrição da imagem, classes ou ids para seleção e o endereço de uma imagem, que será utilizada por navegadores que ainda não suportam a tag picture.

Exemplo de tag picture.

No exemplo acima, será analisado primeiro a media query min-width: 800px. Se ela combinar com a largura de tela do viewport do dispositivo, ou seja, 800 pixels ou maior, será carregado o panorama-full, de acordo com a resolução da tela.

Do contrário, os próximos sources serão analisados, até encontrar um que combine. Se nenhum estiver de acordo ou o navegador não suporta a tag picture, será adotada a imagem da tag img.

Uma imagem para todas as resoluções de tela

O grande problema de se gerar imagens com o dobro das dimensões para atender telas Retina, é o fato de o tamanho do arquivo também aumentar muito.

Este inconveniente estimulou a comunidade de programadores e designers na busca de uma solução. E ela não demorou muito a surgir. Uma técnica chamada compressive images têm sido bastante aceita como solução razoável.

Para telas normais, não Retina, os designers já recomendam exportar as imagens do seu editor com uma qualidade de 80%. Isso porque, aqueles 20% retirados não seriam perceptíveis ao olho humano. Dessa forma, obtém-se um arquivo menor.

A técnica surgiu da seguinte constatação: uma imagem exportada com qualidade bem baixa, algo em torno de 20%, por exemplo, ao ser renderizada em uma tela Retina, onde os pixels são muito pequenos e estão bem próximos uns dos outros, fica visualmente nítida e os detalhes são preservados.

Dessa forma, mesmo a imagem possuindo o dobro das dimensões, como sua qualidade é baixa, o tamanho do arquivo fica parecido com o da imagem antes de ser redimensionada.

Uma vez que o tamanho do arquivo agora já não é mais um problema, podemos usar essa única imagem para todas as resoluções, através de uma tag img convencional. Não esquecendo de limitar a imagem para a metade de suas dimensões.

Assim, em uma tela retina, onde a densidade de pixels é muito alta, nem notamos a qualidade menor do JPEG. E na tela comum, o fato de o navegador apertar a imagem para a metade de suas dimensões, fará com que ela fique boa também, equivalente a uma imagem 1x de alta qualidade.

Essa sacada permitiu contornar o problema de imagens JPEG muito pesadas para que ficassem boas em telas retina. Mas, e os arquivos PNG? Eles não têm qualidade controlável como o JPEG, então não é possível adotar uma estratégia semelhante. Como fazer?

Muita coisa que se fazia antigamente com PNG, hoje em dia já é feita com SVG e Icon Fonts, que suportam retina automaticamente. É o caso de gráficos, desenhos, ícones, elementos de interface e logos.

Nos casos em que realmente preciso de um PNG, como em um print de tela por exemplo, estou optando por utilizar a variação de 8 bits (PNG-8), para imagens com até 256 cores.

O Sérgio Lopes em seu livro, recomenda servir, nesse caso, a imagem de acordo com a resolução de tela do usuário e comenta que tem preferido somente a versão retina para todas as telas. Eu testei os prints que tenho em PNG-8 nas telas 2, 1.5 e 1x. No meu caso, a diferença de qualidade não compensa onerar o usuário com uma imagem 2x, já que a imagem 1x se mostrou satisfatória nas resoluções de telas em que testei.

Ir para o topo