Imagens responsivas

Este codelab faz parte do curso Developing Progressive Web Apps, desenvolvido pela equipe de treinamento do Google Developers. Você aproveitará mais o curso se fizer os codelabs em sequência.

Para ver todos os detalhes sobre o curso, consulte a Visão geral do desenvolvimento de Progressive Web Apps.

Introdução

Este laboratório mostra como criar uma imagem da página da Web boa em todos os dispositivos.

O que você vai aprender

  • Como tornar suas imagens responsivas para que elas sejam dimensionadas de forma adequada para vários formatos
  • Como usar srcset e sizes para exibir a imagem certa para a largura da janela de visualização.
  • Como usar picture e source em combinação com consultas de mídia para que as imagens da página respondam automaticamente à medida que a janela é redimensionada.

O que você precisa saber

  • HTML e CSS básicos

O que é necessário

  • Editor de texto
  • Computador com acesso ao terminal/shell

Faça o download ou clone o repositório pwa-training-labs do GitHub e instale a versão LTS do Node.js, se necessário.

Se você não tiver um servidor de desenvolvimento local preferido, instale o pacote http-server do Node.js:

npm install http-server -g

Navegue até o diretório responsive-images-lab/app/ e inicie o servidor:

cd responsive-images-lab/app
http-server -p 8080 -a localhost -c 0

Você pode encerrar o servidor a qualquer momento usando o Ctrl-c.

Abra seu navegador e acesse localhost:8080/.

Observação: cancele o registro de todos os service workers e limpe todos os caches de service worker do localhost para que não interfiram no laboratório. No Chrome DevTools, você pode fazer isso clicando em Limpar dados do site na seção Limpar armazenamento da guia Aplicativo.

Se você tiver um editor de texto que permita abrir um projeto, abra a pasta responsive-images-lab/app/. Isso facilita a organização. Caso contrário, abra a pasta no sistema de arquivos do computador. A pasta app/ é onde você criará o laboratório.

Essa pasta contém:

  • A pasta images contém amostras de imagens, cada uma com várias versões em diferentes resoluções.
  • index.html é a página HTML principal do nosso site/aplicativo de amostra
  • styles/main.css é a folha de estilos em cascata do site de amostra.

Antes de tornar as imagens responsivas, vamos garantir que elas não transbordem a tela.

Substitua TODO 2 em styles/main.css pelo seguinte código:

img {
  max-width: 100%;
}

Salve o código e atualize a página no seu navegador. Tente redimensionar a janela. As larguras das imagens precisam permanecer dentro da janela.

Explicação

O valor em max-width representa uma porcentagem do elemento contêiner. Nesse caso, o elemento article.

Observação: você também pode especificar max-width em termos de largura da janela de visualização usando unidades vw (por exemplo, 100vw). Nesse caso, estamos usando um valor percentual para manter as imagens com a mesma largura do texto.

O objetivo é fazer com que o navegador busque a versão da imagem com as menores dimensões que ainda sejam maiores do que o tamanho final da imagem. O srcset permite listar um conjunto de imagens em diferentes resoluções para o navegador escolher ao buscar a imagem. A escolha do navegador depende das dimensões da janela de visualização, do tamanho da imagem em relação à janela de visualização, da densidade de pixels do dispositivo do usuário e das dimensões do arquivo de origem.

Adicionar um srcset a uma imagem

Para concluir TODO 3.1 no index.html, adicione o seguinte atributo srcset ao elemento img que contém a imagem do SFO:

srcset="images/sfo-1600_large.jpg, images/sfo-1000_large.jpg, images/sfo-800_medium.jpg, images/sfo-500_small.jpg"

Salve o código e atualize a página no navegador. Abra as Ferramentas para Desenvolvedores do navegador e veja as solicitações de rede. Tente atualizar a página em diferentes tamanhos de janela. Você verá que o navegador está buscando images/sfo-1600_large.jpg, independentemente do tamanho da janela.

Explicação

Na pasta images/, há várias versões da imagem SFO, cada uma com resoluções diferentes. Listamos essas variações no atributo srcset para oferecer ao navegador a opção de escolher qual arquivo usar. No entanto, o navegador não consegue determinar os tamanhos dos arquivos antes de carregá-los. Por isso, ele sempre escolhe a primeira imagem da lista.

Adicionar descritores de largura ao srcset

Para carregar o tamanho correto da imagem com base na largura da janela de visualização, é necessário informar ao navegador o tamanho de cada arquivo antes de buscá-los.

Para concluir TODO 3.2 no index.html, adicione descritores de largura ao elemento img do SFO:

srcset="images/sfo-1600_large.jpg 1600w, images/sfo-1000_large.jpg 1000w, images/sfo-800_medium.jpg 800w, images/sfo-500_small.jpg 500w"

Salve o código e atualize a página no navegador. Atualize a página em vários tamanhos de janela e verifique as solicitações da rede para ver qual versão da imagem é buscada em cada tamanho. Em uma tela de 1x, o navegador busca sfo-500_small.jpg quando a janela é mais estreita que 500px, sfo-800_medium.jpg quando é mais estreita que 800px e assim por diante.

Observação: se uma versão maior de uma imagem estiver disponível no cache do navegador (HTTP), alguns navegadores poderão carregar essa imagem mesmo que não seja a especificada por srcset. Se o navegador já tiver uma imagem de resolução mais alta armazenada localmente, por que não a usar? Para desativar essa função no laboratório, confirme se o cache HTTP está desativado nas ferramentas para desenvolvedores.

Observação: no Chrome, com o DevTools aberto, as dimensões da janela do navegador aparecem enquanto estão sendo redimensionadas. Veja a imagem abaixo. Esse recurso será muito útil durante todo o codelab.

chrome-dimensions.png

Explicação

Ao adicionar um descritor de largura a cada arquivo no srcset, informamos ao navegador a largura de cada imagem em pixels antes de buscar a imagem. O navegador pode usar essas larguras para decidir qual imagem buscar com base no tamanho da janela. Ela busca a imagem com a menor largura que ainda é maior que a largura da janela de visualização.

Observação:você também pode especificar uma densidade de pixels em vez de uma largura. No entanto, não é possível especificar as densidades e larguras de pixel no mesmo atributo srcset. Veremos como usar densidades de pixel em uma seção posterior.

Exibir uma imagem com metade da largura da janela de visualização (50 vw)

Substitua TODO 4.1 no arquivo styles/main.css pelo seguinte código:

img#sfo {
  transition: width 0.5s;
  max-width: 50vw;
}

Salve o código e atualize a página no navegador. Tente atualizar a página em vários tamanhos de janela e verifique as solicitações de rede em cada tamanho. O navegador está buscando as mesmas imagens de tamanho que antes.

Explicação

Como o CSS é analisado após o HTML no momento da execução, o navegador não consegue saber qual será o tamanho final da imagem ao buscá-la. A menos que seja solicitado de outra forma, o navegador presume que as imagens serão exibidas em 100% da largura da janela de visualização e vai buscar as imagens com base nisso. Precisamos de uma maneira de informar ao navegador com antecedência se as imagens serão exibidas em um tamanho diferente.

Adicionar o atributo de tamanhos à imagem

Podemos dar um atributo sizes a img para informar ao navegador o tamanho da imagem antes que ela seja buscada.

Para concluir TODO 4.2 no index.html, adicione sizes="50vw" ao elemento img para que ele fique assim:

<img id="sfo" src="images/sfo-500_small.jpg" srcset="images/sfo-1600_large.jpg 1600w, images/sfo-1000_large.jpg 1000w, images/sfo-800_medium.jpg 800w, images/sfo-500_small.jpg 500w" sizes="50vw" alt="View from aircraft window near San Francisco airport">

Salve o código e atualize a página no navegador. Atualize a página em vários tamanhos de janela e verifique as solicitações de rede sempre. Você verá que, para os mesmos tamanhos de janela aproximado usados para testar a etapa anterior, o navegador está buscando uma imagem menor.

Explicação

O valor de sizes corresponde ao valor de max-width da imagem no CSS. Agora o navegador tem tudo que é necessário para escolher a versão correta da imagem. O navegador sabe a própria largura da janela de visualização e a densidade de pixels do dispositivo do usuário. Além disso, fornecemos a ele as dimensões dos arquivos de origem (usando o descritor de largura) e os tamanhos das imagens em relação à janela de visualização (usando o atributo sizes).

Mais informações

Adicionar uma consulta de mídia ao CSS

Podemos usar consultas de mídia para redimensionar imagens em tempo real com base na largura da janela de visualização.

Substitua TODO 5.1 em styles/main.css pelo seguinte código:

@media screen and (max-width: 700px) {
  img#sfo {
    max-width: 90vw;
    width: 90vw;
  }
}

Salve o código e atualize a página no navegador. Diminua a janela para menos de 700 px. No Chrome, as dimensões da janela de visualização são exibidas na tela se o DevTools estiver aberto. A imagem deve ser redimensionada para preencher 90% da largura da janela.

Explicação

A consulta de mídia testa a largura da janela de visualização e aplica o CSS quando a janela de visualização tem menos de 700 px de largura.

Mais informações

Adicionar a consulta de mídia ao atributo "sizes"

Podemos informar o navegador sobre a consulta de mídia no atributo sizes para que ela busque a imagem correta quando a imagem mudar de tamanho.

Para concluir o TODO 5.2 no index.html, atualize o atributo sizes na imagem do SFO:

sizes="(max-width: 700px) 90vw, 50vw"

Salve o código e atualize a página no navegador. Redimensione a janela do navegador para que ela tenha 600 px de largura. Em uma tela de 1x, o navegador deve buscar sfo-800_medium.jpg.

Podemos usar os elementos picture e source em combinação com consultas de mídia para mudar a origem da imagem conforme a janela é redimensionada.

Substitua TODO 6 em index.html pelo seguinte código:

<figure>
    <picture>
    <source media="(min-width: 750px)"
            srcset="images/horses-1600_large_2x.jpg 2x,
                    images/horses-800_large_1x.jpg" />
    <source media="(min-width: 500px)"
            srcset="images/horses_medium.jpg" />
    <img src="images/horses_small.jpg" alt="Horses in Hawaii">
    </picture>
    <figcaption>Horses in Hawaii</figcaption>
</figure>

Salve o código e atualize a página no navegador. Tente redimensionar a janela do navegador. Você verá a imagem mudar em 750 px e 500 px.

Explicação

O elemento picture permite definir vários arquivos de origem usando a tag source. Isso é diferente de simplesmente usar uma tag img com o atributo srcset, porque a tag de origem permite adicionar itens como consultas de mídia a cada conjunto de origens. Em vez de definir o tamanho das imagens para o navegador e permitir que ele decida quais arquivos usar, podemos definir as imagens que serão usadas em cada tamanho de janela.

Incluímos várias versões da imagem de amostra, cada uma com resoluções diferentes e cortadas para tornar o foco da imagem visível em tamanhos menores. No código acima, com mais de 750 px, o navegador buscará horses-1600_large_2x.jpg (se o dispositivo tiver uma tela 2x) ou horses-800_large_1x.jpg. Se a largura da janela for menor que 750 px, mas maior que 500 px, o navegador buscará horses_medium.jpg. Com menos de 500 px, o navegador busca a imagem substituta, horses_small.jpg.

Observação:se o navegador do usuário não for compatível com o elemento picture, ele buscará o que estiver no elemento img. O elemento picture é usado apenas para especificar várias fontes para o elemento img contido nele. O elemento img é o que exibe a imagem.

Mais informações

Você aprendeu a melhorar a aparência das imagens na sua página da Web em todos os dispositivos.

Recursos

Saiba mais sobre como automatizar o processo

Saiba mais sobre srcset e tamanhos

Saiba mais sobre a direção de arte

Para ver todos os codelabs no curso de treinamento de PWA, consulte o codelab de boas-vindas do curso.