Para prever um candidato de imagem responsiva, resolva sizes para obter uma largura CSS, multiplique-a pela proporção de pixels do dispositivo e compare esse valor com srcset. Em seguida, verifique a URL selecionada: os navegadores têm liberdade para fazer a escolha final.

Este passo a passo é para quem está verificando uma página da web criada por conta própria no Chrome em um Mac. Você calculará os candidatos prováveis, testará uma página local com formas abstratas originais e distinguirá uma declaração de tamanho enganosa do comportamento normal de seleção do navegador.

O que sizes, srcset e DPR informam ao navegador?

Com descritores de largura, srcset lista os recursos disponíveis e suas larguras intrínsecas em pixels. Um descritor como 800w deve descrever uma imagem que tenha de fato 800 pixels de largura. Mantenha os descritores de largura e os descritores de densidade, como 2x, em conjuntos de fontes separados; misturá-los em um único srcset é inválido. A referência do elemento de imagem da MDN documenta esses requisitos.

sizes fornece a largura de exibição pretendida para a seleção do recurso. O navegador avalia as condições em ordem e usa a primeira entrada correspondente. Coloque a alternativa sem condição no final. Os tamanhos das fontes aceitam comprimentos como 480px, 50vw e calc(100vw - 32px); valores percentuais como 50% não são larguras de slot válidas. Uso de imagens responsivas em HTML

O CSS controla as dimensões exibidas. Trate seu CSS e a lista explícita de sizes como duas descrições que precisam permanecer alinhadas: uma determina o layout, enquanto a outra informa a seleção do recurso. Alterar apenas sizes não implementa o layout correspondente. Padrão HTML: atributos Sizes

DPR descreve a relação entre pixels físicos e pixels CSS. Consulte window.devicePixelRatio em vez de presumir um valor com base no modelo do Mac ou no nome da tela. O zoom da página pode alterar esse valor, assim como mover uma janela entre telas. O zoom com gesto de pinça não altera o DPR. MDN: Window.devicePixelRatio

Como calcular o candidato provável?

Para um tamanho de fonte resolvido S, uma largura de recurso W e DPR D, use estes dois cálculos equivalentes:

Largura do recurso-alvo = S × D
Densidade efetiva do candidato = W ÷ S

O modelo de processamento HTML normaliza os descritores de largura dividindo a largura de cada candidato pelo tamanho da fonte. A MDN também explica a previsão prática como a multiplicação da dica de tamanho pelo DPR. Padrão HTML: Normalização das densidades das fontes, MDN: HTMLImageElement.sizes

Para uma estimativa prática, escolha o menor candidato que seja igual ou superior à largura-alvo. Se todos os candidatos forem menores que o alvo, identifique o maior disponível e registre a diferença. Essa é uma regra explícita de previsão para os exercícios abaixo. O padrão HTML deixa a seleção final definida pela implementação; ele não exige que todos os navegadores sigam essa regra de arredondamento. Padrão HTML: Seleção de uma fonte de imagem

Considere esta lista de tamanhos de fonte, associada a candidatos 480w, 800w, 1200w e 1440w:

(max-width: 600px) calc(100vw - 32px),
(max-width: 1200px) calc(50vw - 32px),
568px

100vw representa a largura da janela de visualização e 50vw representa metade dessa largura. Essas unidades se referem à janela de visualização, não ao contêiner pai da imagem. Valores e unidades CSS: comprimentos percentuais da janela de visualização

A tabela a seguir contém cálculos ilustrativos, não resultados registrados de navegadores. A última coluna aplica a regra de previsão indicada.

Largura da janela de visualização, px CSS DPR Tamanho de fonte resolvido, px CSS Largura do recurso-alvo, px Candidato previsto
600 1 568 568 800w
600 2 568 1.136 1200w
601 2 268,5 537 800w
1.000 1 468 468 480w
1.000 2 468 936 1200w
1.400 2 568 1.136 1200w
1.400 3 568 1.704 1440w, abaixo do alvo

A transição de 600 para 601 pixels CSS é especialmente útil para testar. Em 600, a primeira condição fornece um slot quase da largura total. Em 601, a segunda condição fornece um slot muito mais estreito. Assim, uma janela de visualização mais larga produz uma imagem-alvo menor. Isso decorre diretamente deste contrato de layout definido pelo autor.

Em uma janela de visualização de 1.000 pixels e DPR 2, o tamanho da fonte é de 468 pixels CSS. Os quatro candidatos têm densidades efetivas de aproximadamente 1.03x, 1.71x, 2.56x e 3.08x. Pela nossa regra de previsão, o candidato 1200w é o primeiro a superar a densidade-alvo de 2x.

Como montar um teste local completo?

Use um Mac com Chrome e Python 3.8 ou posterior instalado. Salve o programa completo a seguir como responsive_demo.py em um editor de texto simples. Ele gera quatro arquivos PNG com o mesmo retângulo e círculo, cria uma página correspondente e inicia um servidor local. Todos os arquivos gerados são colocados em um novo diretório temporário, para que arquivos existentes não sejam sobrescritos.

A página usa deliberadamente uma imagem carregada de imediato e tamanhos de fonte explícitos. As larguras definidas no CSS correspondem aos três casos usados na tabela de cálculo. O servidor usa o ThreadingHTTPServer documentado pelo Python e um manipulador de requisições baseado em diretório. Python: http.server

from functools import partial
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
import struct
import tempfile
import zlib


def chunk(kind, data):
    return (
        struct.pack("!I", len(data)) + kind + data
        + struct.pack("!I", zlib.crc32(kind + data))
    )


def make_png(width):
    height = width // 2
    rows = []
    for y in range(height):
        row = bytearray()
        for x in range(width):
            color = (242, 244, 248)
            if width // 8 <= x < width // 2 and height // 4 <= y < 3 * height // 4:
                color = (70, 100, 160)
            if (x - 3 * width // 4) ** 2 + (y - height // 2) ** 2 < (height // 5) ** 2:
                color = (220, 160, 60)
            row.extend(color)
        rows.append(b"\x00" + row)
    header = struct.pack("!IIBBBBB", width, height, 8, 2, 0, 0, 0)
    return (
        b"\x89PNG\r\n\x1a\n"
        + chunk(b"IHDR", header)
        + chunk(b"IDAT", zlib.compress(b"".join(rows)))
        + chunk(b"IEND", b"")
    )


page = '''<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shape A candidate test</title>
<style>
  body { margin: 0; padding: 16px; font-family: sans-serif; }
  #shape { display: block; width: calc(100vw - 32px); height: auto; }
  @media (min-width: 600.01px) {
    #shape { width: calc(50vw - 32px); }
  }
  @media (min-width: 1200.01px) {
    #shape { width: 568px; }
  }
</style>
<p>Shape A: rectangle and circle</p>
<img id="shape" src="shape-a-800.png" width="1440" height="720"
     alt="Blue rectangle and amber circle on a pale background"
     srcset="shape-a-480.png 480w, shape-a-800.png 800w,
             shape-a-1200.png 1200w, shape-a-1440.png 1440w"
     sizes="(max-width: 600px) calc(100vw - 32px),
            (max-width: 1200px) calc(50vw - 32px), 568px">
</html>
'''

root = Path(tempfile.mkdtemp(prefix="responsive-shapes-"))
for width in (480, 800, 1200, 1440):
    (root / f"shape-a-{width}.png").write_bytes(make_png(width))
(root / "index.html").write_text(page, encoding="utf-8")
handler = partial(SimpleHTTPRequestHandler, directory=str(root))
with ThreadingHTTPServer(("127.0.0.1", 0), handler) as server:
    print(f"Files: {root}", flush=True)
    print(f"Open http://127.0.0.1:{server.server_port}/", flush=True)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass

No Terminal, navegue até a pasta onde salvou o programa e execute:

python3 responsive_demo.py

Abra no Chrome o endereço local exibido pelo programa. Mantenha o Terminal em execução durante o teste; quando terminar, pressione Control+C nele. O programa solicita uma porta disponível, então use o endereço exibido em vez de presumir um número de porta fixo.

Os limites do CSS usam 600.01px e 1200.01px para os valores inteiros da largura da janela de visualização no teste em computador. Teste os valores inteiros exatos da tabela. Ao adaptar o exemplo a um layout de produção, alinhe os pontos de quebra reais do CSS às condições dos tamanhos de fonte, incluindo qualquer comportamento de largura fracionária.

Como verificar a seleção no Chrome em um Mac?

Clique com o botão direito na forma e selecione Inspecionar para abrir o DevTools com o elemento de imagem selecionado. O Chrome documenta essa opção como uma maneira direta de inspecionar um elemento e os estilos aplicados a ele. Abrir o Chrome DevTools

  1. Clique em Alternar barra de ferramentas do dispositivo e escolha Responsivo em Dimensões.
  2. Defina a largura da janela de visualização como 1000.
  3. No menu Mais opções da barra de ferramentas, escolha Adicionar proporção de pixels do dispositivo e selecione DPR 2.
  4. Se necessário, use Mais opções, depois Adicionar tipo de dispositivo e selecione Computador.
  5. Abra Rede, ative Desativar cache e recarregue a página com o DevTools aberto.
  6. Encontre a imagem solicitada filtrando por shape-a.

O Chrome documenta os controles de janela de visualização, DPR e tipo de dispositivo no guia do Modo de dispositivo e o controle de cache na referência dos recursos de rede.

Após o carregamento da página, execute este trecho completo de diagnóstico no Console do DevTools:

(() => {
  const image = document.getElementById("shape");
  if (!image) throw new Error("The Shape A image was not found.");

  const viewport = window.innerWidth;
  const slot = window.matchMedia("(max-width: 600px)").matches
    ? viewport - 32
    : window.matchMedia("(max-width: 1200px)").matches
      ? viewport / 2 - 32
      : 568;

  console.table({
    viewportCSSPixels: viewport,
    devicePixelRatio: window.devicePixelRatio,
    declaredSlotCSSPixels: slot,
    renderedWidthCSSPixels: image.getBoundingClientRect().width,
    targetResourcePixels: slot * window.devicePixelRatio,
    selectedURL: image.currentSrc,
    naturalWidthCSSPixels: image.naturalWidth
  });
})();

Este trecho calcula o slot declarado especificamente para esta demonstração; não é um analisador geral de sizes. Compare o slot declarado com a largura renderizada e, em seguida, compare o nome do arquivo selecionado com a tabela de previsão.

currentSrc informa a URL completa selecionada pelo navegador. Isso não confirma que o recurso foi carregado com sucesso; por isso, verifique também a requisição da imagem e o resultado exibido. Consultar src revelaria apenas o atributo alternativo neste exemplo. MDN: HTMLImageElement.currentSrc

Evite interpretar naturalWidth como a largura codificada do PNG. Trata-se de uma largura corrigida pela densidade, expressa em pixels CSS. Neste exemplo controlado, as dimensões e o nome do arquivo gerado identificam a largura do recurso. MDN: HTMLImageElement.naturalWidth

Repita o teste em 600 e 601 pixels CSS, recarregando a página para cada condição. Registre a janela de visualização, o DPR informado, o slot, o nome do arquivo selecionado e se a requisição foi concluída. Esses registros distinguem um resultado repetível em um carregamento novo de uma sequência de escolhas feitas ao redimensionar uma página já carregada.

O que verificar quando a previsão for diferente?

Revise os dados de entrada antes de alterar a lista de candidatos:

  1. Verifique a família de descritores. Com descritores de densidade, como 1x e 2x, não aplique o cálculo de descritores de largura por meio de sizes.
  2. Verifique a primeira condição correspondente. Uma condição anterior que corresponda tem precedência sobre as entradas posteriores.
  3. Compare as larguras declarada e renderizada. Uma declaração de 100vw pode exagerar um slot que o CSS limita a uma coluna estreita.
  4. Leia o DPR real. Confira novamente após alterar o zoom da página ou trocar de tela.
  5. Compare recarregamentos controlados. Mantenha a mesma janela de visualização, DPR e condições de carregamento ao repetir o teste.
  6. Verifique a disponibilidade do recurso. Uma URL selecionada e uma imagem exibida com sucesso são observações distintas.

A ausência de tamanhos de fonte explícitos válidos ou o uso de valores inválidos pode levar o analisador HTML ao padrão 100vw. Isso pode explicar um alvo surpreendentemente grande para uma imagem estreita. Forneça uma lista precisa de tamanhos de fonte em vez de presumir que o navegador inferirá pela CSS a largura pretendida para a coluna. Padrão HTML: Análise de um atributo sizes

Se a página usar um elemento picture, determine qual ramo de fonte se aplica antes de calcular as densidades. A seleção da fonte precede a escolha entre os candidatos desse ramo; diferentes recortes fazem parte desse mecanismo de direção de arte. Uso de imagens responsivas em HTML

Quais limites de compatibilidade afetam este método?

A MDN classifica a propriedade sizes como amplamente disponível nos navegadores, mas isso não significa que todas as palavras-chave mais recentes tenham o mesmo nível de suporte. As condições explícitas usadas aqui permitem um teste direto, sem depender do dimensionamento automático. MDN: HTMLImageElement.sizes

sizes="auto" é válido para imagens carregadas sob demanda e permite que a seleção use a largura definida pelo layout. Se você adotá-lo, mantenha tamanhos alternativos explícitos após auto para navegadores que não oferecem suporte à palavra-chave e informe as dimensões da imagem. Não o substitua neste exemplo de carregamento imediato sem alterar esses pré-requisitos. A referência do elemento de imagem da MDN

Os controles de dispositivo do Chrome testam o comportamento do Chrome sob condições emuladas. Eles não demonstram as escolhas de candidatos do Safari ou do Firefox. O Chrome também descreve o Modo de dispositivo como uma aproximação; portanto, teste diretamente em outro navegador quando o comportamento dele for relevante. Chrome DevTools: limitações do Modo de dispositivo

Uma previsão útil termina com um registro verificável: o conjunto de fontes aplicável, o tamanho de fonte resolvido, o DPR informado, o alvo calculado e o currentSrc observado. Quando esses dados coincidem com o layout definido pelo autor, você consegue explicar com clareza a escolha do recurso e identificar se a próxima alteração deve ser feita no CSS, em sizes ou nas larguras de imagem disponíveis.

Fontes