Curso de HTML / Imagens responsivas: srcset, sizes e picture

As imagens responsivas oferecem ao navegador arquivos com diferentes resoluções ou composições para que ele possa escolher um adequado para a exibição. Use srcset e sizes para as escolhas de resolução da mesma imagem, e picture quando uma tela mais estreita exigir um recorte diferente.

Obtenha os arquivos de imagem de exemplo

Estes exemplos usam a mesma foto do lago em três larguras e um recorte quadrado que mantém a árvore em destaque. Faça o download dos arquivos na mesma pasta que seu arquivo HTML para testar os URLs relativos inalterados. Prepare o arquivo, o texto alternativo e as dimensões usando os princípios em Imagens: img, texto alternativo e dimensões.

Os três primeiros preservam a cena e a proporção. O arquivo quadrado tem uma composição diferente para uma exibição estreita.

Escolher a resolução da imagem com srcset e sizes

Os descritores 480w, 960w e 1600w em srcset fornecem a largura real em pixels de cada arquivo. sizes descreve a largura de layout esperada da imagem de acordo com diferentes condições da janela de exibição.

<img class="example-fluid"
  src="html-image-sample-lake-tree-960-v1.webp"
  srcset="html-image-sample-lake-tree-480-v1.webp 480w,
          html-image-sample-lake-tree-960-v1.webp 960w,
          html-image-sample-lake-tree-1600-v1.webp 1600w"
  sizes="(max-width: 800px) 100vw, 800px"
  alt="Uma árvore em um ilhote no meio de um lago, com montanhas ao fundo"
  width="1600" height="900">

Isso pressupõe que a imagem tem aproximadamente a mesma largura da janela de exibição até 800 pixels CSS, e que não ultrapassa 800 pixels CSS além disso. Se seu layout for diferente, modifique sizes para que corresponda. src fornece uma solução alternativa para ambientes sem suporte a srcset.

.example-fluid {
  display: block;
  width: 100%;
  max-width: 800px;
  height: auto;
}

Este CSS aplica-se apenas ao primeiro exemplo, que possui a classe example-fluid. O navegador também pode levar em consideração a densidade de pixels do dispositivo e o zoom. Portanto, uma viewport estreita não garante que o arquivo de 480 pixels será escolhido. sizes descreve os pixels CSS exibidos, e não a largura do arquivo baixado.

Use descritores de densidade para uma largura de exibição fixa

Se uma imagem sempre é exibida com 480 pixels de largura CSS, você pode sugerir candidatos 1x e 2x. Não use sizes com este formato.

<img class="example-fixed"
  src="html-image-sample-lake-tree-480-v1.webp"
  srcset="html-image-sample-lake-tree-480-v1.webp 1x,
          html-image-sample-lake-tree-960-v1.webp 2x"
  alt="Uma árvore em um ilhote no meio de um lago, com montanhas ao fundo"
  width="480" height="270">
.example-fixed {
  display: block;
  width: 480px;
  height: auto;
}

O CSS do primeiro exemplo não se aplica a esta imagem. Este CSS define a largura exibida em 480 pixels, portanto a imagem pode ultrapassar um contêiner mais estreito. Se a largura de exibição precisar mudar dependendo do layout, use a abordagem w e sizes mencionada anteriormente. Não misture os descritores w e x em um mesmo srcset.

Alterar o recorte com picture

picture pode oferecer uma composição diferente em vez de apenas uma resolução diferente. Este exemplo utiliza o recorte quadrado para larguras de janela de até 600 pixels e uma imagem em formato paisagem caso contrário.

<picture class="example-picture">
  <source media="(max-width: 600px)"
          srcset="html-image-sample-lake-tree-square-800-v1.webp"
          width="800" height="800">
  <img src="html-image-sample-lake-tree-960-v1.webp"
       alt="Uma árvore em um ilhote no meio de um lago, com montanhas ao fundo"
       width="960" height="540">
</picture>

Escolher um recorte e ajustar sua largura de exibição são ações distintas. Adicione este CSS no elemento style do head ou na folha de estilo vinculada para que a imagem picture se ajuste a um elemento pai estreito enquanto mantém sua proporção.

.example-picture img {
  display: block;
  max-width: 100%;
  height: auto;
}

Recorte quadrado de uma foto de lago com foco na árvore

A foto acima mostra o arquivo quadrado usado em telas estreitas; esta foto no próprio artigo não muda dependendo da largura da janela. picture sempre requer um elemento img com conteúdo de reserva e alt. Cada source fornece uma condição e um arquivo candidato; o texto alternativo da imagem pertence ao img.

Verifique qual imagem o navegador selecionou

Salve os quatro arquivos de imagem, mantendo seus nomes de arquivo, ao lado de index.html. Coloque um exemplo HTML dentro de body e seu CSS em um elemento style em head ou em uma folha de estilo separada. Para testar em relação à largura real da janela em dispositivos móveis, adicione <meta name="viewport" content="width=device-width, initial-scale=1"> a head.

  1. Abra index.html em um navegador e abra o painel Rede das ferramentas de desenvolvimento.
  2. Altere a largura da janela de visualização, desative o cache e recarregue a página. Verifique os nomes de arquivo das requisições de imagem para ver quais candidatos foram carregados.
  3. Para o exemplo picture, recarregue uma vez com uma largura de janela de exibição de 600 pixels ou menos e uma vez acima de 600 pixels. Verifique o recorte quadrado na largura mais estreita e o arquivo paisagem na largura mais larga.

Você também pode verificar esses valores no console. currentSrc mostra o URL da imagem atualmente selecionada pelo navegador. O primeiro comando seleciona o exemplo srcset; o segundo seleciona o exemplo picture.

document.querySelector('.example-fluid').currentSrc
document.querySelector('picture img').currentSrc

Mesmo com a mesma largura de janela, a densidade de pixels e o zoom podem mudar qual arquivo srcset é selecionado. Se um arquivo maior já estiver carregado, reduzir a janela não o substituírá imediatamente por um arquivo menor. Mude as condições, desative o cache e recarregue antes de comparar.

Verifique a mudança de resolução e a adaptação do enquadramento

Situação Mecanismo A verificar
Mesma composição, largura fluida Descritores w + sizes Verifique se sizes descreve o layout e se currentSrc nomeia um candidato proposto
Mesma composição, largura fixa 1x / 2x Os candidatos de densidade selecionam um arquivo; eles não tornam a largura de exibição responsiva
Composição diferente dependendo da janela de exibição picture + source[media] Compare o recorte quadrado em 600px com o paisagem em 601px

A janela de exibição é a área do navegador usada para organizar a página. A densidade de pixels do dispositivo conecta os pixels CSS aos pixels físicos da tela. A densidade, o zoom e o estado do cache podem afetar a seleção da resolução mesmo na mesma largura da janela de exibição, portanto, não prometa um nome de arquivo srcset fixo. Teste a condição de mídia da adaptação do enquadramento separadamente da mudança de resolução.

Se a imagem errada for selecionada

  • Verifique se cada descritor w corresponde à largura real em pixels do arquivo.
  • Compare sizes com a largura CSS em cada tamanho de janela.
  • Use arquivos de composição idêntica para alteração de resolução e recortes separados com picture.
  • Mantenha um alt significativo no img dentro de picture.

Para regras detalhadas de seleção, consulte o guia de imagens responsivas MDN e a especificação de imagens HTML WHATWG.