Pular para o conteúdo
ImageZap

Imagens responsivas com srcset e sizes

srcset e sizes permitem que cada dispositivo baixe apenas os pixels de que precisa. Bem configurados, reduzem o peso das imagens no celular a uma fração.

Por 3 min de leitura

O problema que eles resolvem

Uma mesma imagem é exibida com 360 px de largura em um celular, 768 px em um tablet e 1400 px em um notebook, e ainda em telas com densidades de 1x, 2x ou 3x. Se você serve um único arquivo, ou ele é grande demais para o celular (você desperdiça dados e piora o LCP), ou pequeno demais para o desktop (fica borrado).

Com srcset você descreve quais arquivos tem e com sizes em que tamanho a imagem será exibida. Com essa informação, o navegador —que conhece a largura da janela e a densidade da tela— escolhe o arquivo ideal.

srcset com descritores de largura (w)

É a forma mais útil e a que você deveria usar quase sempre:

<img
  src="foto-1280.jpg"
  srcset="foto-640.jpg 640w, foto-1280.jpg 1280w, foto-1920.jpg 1920w"
  sizes="(min-width: 1024px) 800px, 100vw"
  width="1920" height="1080"
  alt="Descrição da foto">

Cada entrada é arquivo largura_real_em_pixels seguido de w. O src funciona como fallback para navegadores muito antigos.

O atributo sizes

O sizes indica a largura na tela que a imagem vai ocupar, não a do arquivo. É uma lista de condições de media query com uma largura, e um valor final padrão:

sizes="(min-width: 1024px) 800px, (min-width: 640px) 50vw, 100vw"

Lê-se assim: em telas de pelo menos 1024 px, a imagem ocupa 800 px; entre 640 e 1023 px, metade da janela; abaixo disso, a janela inteira.

O navegador multiplica essa largura pela densidade de pixels e escolhe o menor arquivo que a cobre. Por exemplo, em um celular de 390 px de largura a 3x ele precisará de cerca de 1170 px, então vai escolher foto-1280.jpg.

390 pxlargura na tela×3xdensidade=1170 pxnecessária640w1280w✓1920w
Largura do sizes × densidade de pixels = largura necessária. É baixado o menor arquivo que a cobre.

Erros típicos com sizes

  • Omiti-lo. Se você não o colocar, o navegador assume 100vw, e no desktop vai baixar a imagem maior mesmo que ela seja exibida em uma coluna estreita.
  • Colocar a largura do arquivo. O sizes descreve o layout, não os arquivos.
  • Não bater com o CSS. Se o seu CSS mudar, revise o sizes. Você pode conferir no DevTools: a propriedade currentSrc do elemento mostra qual arquivo foi escolhido.

Se você usa loading="lazy", os navegadores baseados no Chromium já aceitam sizes="auto" (você pode escrever sizes="auto, 100vw" como fallback), que calcula o valor a partir do layout real. Só funciona em imagens adiadas.

Se não quiser calcular à mão, o gerador de srcset monta o sizes a partir do seu layout e gera as variantes.

srcset com descritores de densidade (x)

Para imagens de tamanho fixo —um avatar de 64 px, um logotipo— basta indicar densidades:

<img src="avatar-64.png" srcset="avatar-64.png 1x, avatar-128.png 2x" width="64" height="64" alt="">

Não combine w e x no mesmo srcset.

Quais larguras gerar

Não é preciso uma variante para cada dispositivo. Uma regra prática é cobrir saltos de 30% a 50% de peso:

Tipo de imagemLarguras sugeridas
Hero em tela cheia640, 960, 1280, 1920, 2560
Imagem de artigo (coluna de ~800 px)480, 800, 1200, 1600
Card em grade320, 480, 640, 960

No ImageZap, ative Variantes responsivas, marque as larguras e o gerador de código escreverá o srcset com os nomes reais dos arquivos.

srcset dentro de picture

Se você também quiser servir vários formatos, cada <source> leva seu próprio srcset e sizes:

<picture>
  <source type="image/avif" srcset="foto-640.avif 640w, foto-1280.avif 1280w" sizes="(min-width: 1024px) 800px, 100vw">
  <source type="image/webp" srcset="foto-640.webp 640w, foto-1280.webp 1280w" sizes="(min-width: 1024px) 800px, 100vw">
  <img src="foto-1280.jpg" srcset="foto-640.jpg 640w, foto-1280.jpg 1280w" sizes="(min-width: 1024px) 800px, 100vw" width="1280" height="720" alt="…">
</picture>

Não esqueça width e height

Os atributos width e height não fixam o tamanho na tela (isso é papel do CSS), mas permitem que o navegador reserve o espaço com a proporção correta antes de a imagem chegar. Assim você evita saltos de layout (CLS). Combine-os com:

img { max-width: 100%; height: auto; }

Perguntas frequentes

Por que o navegador baixa uma imagem maior que a esperada?

Provavelmente por causa da densidade da tela (um celular a 3x precisa do triplo de pixels) ou porque falta o sizes. Confira o currentSrc no DevTools.

O navegador baixa de novo ao redimensionar a janela?

Ele pode baixar uma variante maior se precisar, mas normalmente não desce para uma menor se já tiver uma maior em cache.

Preciso de srcset se uso uma CDN de imagens?

Muitas CDNs geram as variantes para você, mas você continua precisando escrever srcset e sizes (ou usar um componente que faça isso) para que o navegador escolha.

Quantas variantes são demais?

Mais de 5-6 por formato raramente compensa. Cada variante extra é mais trabalho de geração e cache para uma economia marginal.

Guias relacionados