Imagens responsivas

O texto na Web se ajusta automaticamente à borda da tela para que não transpareça. As imagens, por outro lado, têm um tamanho intrínseco. Se uma imagem for mais larga que a tela, ela vai flutuar e o usuário precisará rolar na horizontal para ver toda a imagem.

Felizmente, o CSS oferece ferramentas para impedir que isso aconteça.

Restringir suas imagens

Na folha de estilo, você pode usar max-inline-size para declarar que as imagens nunca podem ser renderizadas em um tamanho maior que o elemento que as contém.

Compatibilidade com navegadores

  • 57
  • 79
  • 41
  • 12.1

Origem

img {
  max-inline-size: 100%;
  block-size: auto;
}

Também é possível aplicar a mesma regra a outros tipos de conteúdo incorporado, como vídeos e iframes.

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

Com essa regra em vigor, os navegadores reduzem automaticamente as imagens para que caibam na tela.

Duas capturas de tela. A primeira mostra uma imagem se expandindo além da largura do navegador. A segunda mostra a mesma imagem restrita dentro da janela de visualização do navegador.
Restringir a imagem permite que os usuários vejam tudo sem precisar rolar a tela.

Adicionar o valor block-size de auto significa que o navegador preserva a proporção das imagens à medida que elas são redimensionadas.

Às vezes, as dimensões de uma imagem são definidas por um sistema de gerenciamento de conteúdo (CMS) ou outro sistema de envio de conteúdo. Caso seu design exija uma proporção diferente do padrão do CMS, use a propriedade aspect-ratio para preservar o design do site:

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

Infelizmente, isso geralmente significa que o navegador precisa comprimir ou esticar a imagem para fazê-la caber no espaço pretendido.

Perfil de um cachorro lindo e feliz com uma bola na boca, mas a imagem está amassada.
Mudar a proporção da imagem faz com que ela pareça comprimida ou esticada.

Para evitar compressão e alongamento, use a propriedade object-fit.

Compatibilidade com navegadores

  • 32
  • 79
  • 36
  • 10

Origem

Um valor object-fit de contain instrui o navegador a preservar a proporção da imagem, deixando espaço vazio ao redor dela, se necessário.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

Um valor object-fit de cover instrui o navegador a preservar a proporção da imagem, cortando-a, se necessário.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Perfil de um cachorro lindo e feliz com uma bola na boca. Há espaço extra em ambos os lados da imagem. Perfil de um cachorro lindo e feliz com uma bola na boca. A imagem foi cortada nas partes superior e inferior.
A mesma imagem com dois valores diferentes para "object-fit" é aplicado. O primeiro tem o valor "contain" de "object-fit". O segundo tem o valor "cover" de "object-fit".

Mude a posição do corte da imagem com a propriedade object-position. Isso ajusta o foco do corte para que você possa garantir que a parte mais importante da imagem ainda esteja visível.

Compatibilidade com navegadores

  • 32
  • 79
  • 36
  • 10

Origem

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}
Perfil de um cachorro lindo e feliz com uma bola na boca. A imagem foi cortada apenas na parte inferior.
É possível definir object-position para cortar apenas um lado da imagem.

Enviar imagens

Essas regras de CSS informam ao navegador como você quer que as imagens sejam renderizadas. Você também pode fornecer dicas no HTML sobre como o navegador deve lidar com essas imagens.

Dicas de tamanho

Se você souber as dimensões da imagem, sempre inclua os atributos width e height. Mesmo que a imagem seja renderizada em um tamanho diferente devido à regra max-inline-size, o navegador ainda saberá a proporção entre largura e altura e poderá reservar a quantidade certa de espaço. Isso evita que o outro conteúdo pule por aí quando a imagem for carregada.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>
O primeiro vídeo mostra um layout sem dimensões de imagem definidas. Observe como o texto salta quando as imagens são carregadas. No segundo vídeo, as dimensões da imagem foram fornecidas para que o navegador deixe espaço para a imagem e o texto não pule quando a imagem for carregada.

Dicas para o carregamento

Use o atributo loading para informar ao navegador se deve atrasar o carregamento da imagem até que ela esteja na janela de visualização ou perto dela. Para imagens abaixo da dobra, use o valor lazy. O navegador não carregará imagens lentas até que o usuário tenha rolado para baixo o suficiente para que a imagem esteja prestes a ser exibida. Se o usuário nunca rolar, a imagem nunca vai ser carregada.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>
As imagens com carregamento lento aguardam o carregamento até que o usuário esteja prestes a rolar até elas.

Para uma imagem principal acima da dobra, não use loading. Se o site aplicar o atributo loading="lazy" automaticamente, geralmente será possível definir loading como o valor padrão de eager para evitar que as imagens sejam carregadas lentamente:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
>

Prioridade da busca

Para imagens importantes, como a imagem LCP, é possível priorizar ainda mais o carregamento usando a Prioridade de busca definindo o atributo fetchpriority como high:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 fetchpriority="high"
>

Isso instrui o navegador a buscar a imagem imediatamente e em alta prioridade, em vez de esperar que o navegador termine o layout e busque as imagens normalmente.

No entanto, quando você pede para o navegador priorizar o download de um recurso, como uma imagem, ele precisa diminuir a prioridade de outro recurso, como um script ou um arquivo de fonte. Só defina fetchpriority="high" em uma imagem se ela for realmente importante.

Dicas para pré-carregamento

É melhor evitar o pré-carregamento sempre que possível, incluindo todas as imagens no arquivo HTML inicial. No entanto, algumas imagens podem não estar disponíveis, como imagens adicionadas por JavaScript ou uma imagem de plano de fundo CSS.

Você pode usar o pré-carregamento para que o navegador busque essas imagens importantes com antecedência. Para imagens muito importantes, é possível combinar esse pré-carregamento com o atributo fetchpriority:

<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">

Novamente, use esses atributos com moderação para evitar substituir a heurística de priorização do navegador com muita frequência. O uso excessivo delas pode prejudicar o desempenho.

Alguns navegadores oferecem suporte ao pré-carregamento de imagens responsivas com base em srcset usando os atributos imagesrcset e imagesizes. Exemplo:

<link rel="preload" imagesrcset="hero_sm.jpg 1x hero_med.jpg 2x hero_lg.jpg 3x" as="image" fetchpriority="high">

Ao excluir o substituto href, você garante que os navegadores sem srcset ainda pré-carreguem a imagem correta.

Não é possível pré-carregar imagens em diferentes formatos dependendo do suporte do navegador a determinados formatos. Essa tentativa pode resultar em downloads extras que desperdiçam dados do usuário.

Decodificação de imagens

Há também um atributo decoding que você pode adicionar a elementos img. Você pode informar ao navegador que a imagem pode ser decodificada de forma assíncrona para que ele possa priorizar o processamento de outros conteúdos.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

Você pode usar o valor sync se a própria imagem for a parte mais importante do conteúdo a ser priorizada.

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

O atributo decoding não muda a velocidade de decodificação da imagem. Ela só afeta se o navegador espera que essa decodificação da imagem aconteça antes de renderizar outro conteúdo.

Na maioria dos casos, isso não tem muito impacto, mas às vezes pode permitir que o navegador mostre sua imagem ou outro conteúdo um pouco mais rápido. Por exemplo, para um documento grande com muitos elementos que levam tempo para renderizar e com imagens grandes que levam muito tempo para decodificar, definir sync em imagens importantes instrui o navegador a esperar a imagem e renderizar ambas ao mesmo tempo. Como alternativa, você pode definir async para permitir que o navegador mostre conteúdo mais rapidamente e sem esperar a decodificação da imagem.

No entanto, a melhor opção geralmente é tentar evitar tamanhos excessivos de DOM e usar imagens responsivas para reduzir o tempo de decodificação, em vez de usar decoding.

Imagens responsivas com o srcset

Graças a essa declaração max-inline-size: 100%, suas imagens não podem sair dos contêineres. No entanto, se um usuário tiver uma tela pequena e uma rede de baixa largura de banda, fazer com que ele faça o download de imagens do mesmo tamanho que usuários com telas maiores desperdiça dados.

Para corrigir esse problema, adicione várias versões da mesma imagem em tamanhos diferentes e use o atributo srcset para informar ao navegador que esses tamanhos existem e quando usá-los.

Descritor de largura

Você pode definir uma srcset usando uma lista de valores separados por vírgulas. Cada valor é o URL de uma imagem, seguido por um espaço e alguns metadados sobre a imagem, chamados de descritores.

Neste exemplo, os metadados descrevem a largura de cada imagem usando a unidade w. Um w é a largura de um pixel.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

O atributo srcset complementa o src em vez de substituí-lo. Você ainda precisa ter um atributo src válido, mas o navegador pode substituir o valor dele por uma das opções listadas no srcset. Para economizar largura de banda, o navegador só faz o download da imagem maior se necessário.

Tamanhos

Se você estiver usando o descritor de largura, também precisará usar o atributo sizes para fornecer mais informações ao navegador. Isso informa ao navegador o tamanho em que você espera que a imagem seja exibida em diferentes condições. Essas condições são especificadas em uma consulta de mídia.

O atributo sizes usa uma lista separada por vírgulas de consultas de mídia e larguras de imagem.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

Neste exemplo, você está informando ao navegador que, em uma janela de visualização com largura acima de 66em, ele precisa exibir a imagem no máximo um terço da tela (dentro de um layout de três colunas, por exemplo).

Para larguras da janela de visualização entre 44em e 66em, exiba a imagem na metade da largura da tela (como em um layout de duas colunas).

Para algo mais estreito que 44em, mostre a imagem na largura total da tela.

Isso significa que a imagem maior não será necessariamente usada para a tela mais larga. Uma janela de navegador ampla que pode mostrar um layout de várias colunas usa uma imagem que cabe em uma coluna, que pode ser menor do que uma imagem usada para um layout de coluna única em uma tela mais estreita.

Use descritores de tamanho para mudar o layout da página em diferentes tamanhos de tela.

Descritor de densidade de pixels

Você também pode usar descritores para fornecer uma versão alternativa das imagens a ser exibida em telas de alta densidade, a fim de manter as imagens nítidas nas resoluções mais altas que fornecerem.

Duas versões da mesma imagem de um cachorro lindo e feliz com uma bola na boca, uma imagem nítida e outra felpuda.
Imagens com densidades de pixel menores podem parecer imprecisas.

Use o descritor de densidade para descrever a densidade de pixels da imagem em relação à imagem no atributo src. O descritor de densidade é um número seguido pela letra x, como em 1x ou 2x.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

Se small-image.png tiver 300 x 200 pixels e medium-image.png 600 x 400 pixels, medium-image.png poderá ter 2x depois dele na lista srcset.

Não é necessário usar números inteiros. Se outra versão da imagem tiver 450 x 300 pixels, será possível descrevê-la com 1.5x.

Imagens de apresentação

Imagens em HTML são conteúdo. É por isso que você inclui o atributo alt com uma descrição da imagem para leitores de tela e mecanismos de pesquisa.

Se você incorporar uma imagem decorativa, sem conteúdo significativo, use um atributo alt vazio.

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

É necessário sempre incluir o atributo alt, mesmo que ele esteja vazio. Um atributo alt vazio informa ao leitor de tela que a imagem é apresentativa. Um atributo alt ausente não fornece essa informação.

O ideal é que imagens de apresentação ou decorativas sejam incluídas com CSS em vez de HTML. O HTML serve para a estrutura. O CSS serve para apresentação.

Imagens de plano de fundo

Use a propriedade background-image no CSS para carregar imagens de apresentação.

element {
  background-image: url(flourish.png);
}

É possível especificar várias imagens candidatas usando a função image-set para background-image.

A função image-set no CSS é muito parecida com o atributo srcset no HTML. Forneça uma lista de imagens com um descritor de densidade de pixels para cada uma.

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

O navegador escolhe a imagem mais adequada para a densidade de pixels do dispositivo.

Há muitos fatores a serem considerados ao adicionar imagens ao seu site, incluindo:

  • Reservando o espaço certo para cada imagem.
  • Descobrir de quantos tamanhos você precisa.
  • Decidir se a imagem é de conteúdo ou decorativa.

Vale a pena gastar tempo para ajustar suas imagens. Estratégias ruins de imagem podem irritar e frustrar os usuários. Uma boa estratégia de imagens faz com que seu site pareça rápido e nítido, independentemente do dispositivo ou da conexão de rede do usuário.

Há mais um elemento HTML no seu kit de ferramentas para oferecer mais controle sobre suas imagens: o elemento picture.

Teste seu conhecimento

Teste seus conhecimentos sobre imagens.

É necessário adicionar estilos para que as imagens se encaixem na janela de visualização.

Verdadeiro
As imagens sem contenção serão tão grandes quanto seu tamanho natural.
Falso
Os estilos são obrigatórios.

Quando a altura e a largura de uma imagem são forçadas para uma proporção não natural, quais estilos podem ajudar a ajustar a forma como a imagem se encaixa nessas proporções?

object-fit
Especifique como a imagem se ajusta a palavras-chave como contain e cover.
image-fit
Esta propriedade não existe, eu inventei.
fit-image
Esta propriedade não existe, eu inventei.
aspect-ratio
Isso pode causar ou resolver uma proporção de imagem não natural.

Colocar height e width nas imagens impede que o CSS defina um estilo diferente.

Verdadeiro
Pense nelas mais como dicas do que regras.
Falso
O CSS tem uma grande quantidade de opções dinâmicas para dimensionar imagens, mesmo que a altura e a largura estejam alinhadas na tag.

O atributo srcset não _______ o atributo src, mas _______ o atributo.

complementar, substituir
srcset definitivamente não substitui o atributo src.
substituir, complementa
Ela fornece opções adicionais para o navegador, se possível.

A ausência do alt em uma imagem é o mesmo que uma alt vazia.

Verdadeiro
Um atributo alt vazio informa ao leitor de tela que essa imagem é de apresentação.
Falso
A ausência de alt indica que não há nada para um leitor de tela.