Um mergulho profundo no ajuste do objeto e no tamanho do plano de fundo em CSS

Publicados: 2022-03-10
Resumo rápido ↬ Neste artigo, veremos como object-fit e background-size funcionam, quando podemos usá-los e por quê, juntamente com alguns casos de uso práticos e recomendações. Vamos mergulhar.

Nem sempre podemos carregar imagens de tamanhos diferentes para um elemento HTML. Se usarmos uma largura e uma altura que não sejam proporcionais à proporção da imagem, a imagem poderá ser compactada ou esticada. Isso não é bom e pode ser resolvido com object-fit para um elemento img ou usando background-size .

Primeiro, vamos definir o problema. Considere a figura a seguir:

Uma foto bonita e uma imagem espremida em comparação
Uma foto bonita que fica espremida quando usada em um componente de cartão. (Visualização grande)

Por que isso está acontecendo?

Uma imagem terá uma proporção e o navegador preencherá a caixa com essa imagem. Se a proporção da imagem for diferente da largura e altura especificadas para ela, o resultado será uma imagem comprimida ou esticada.

Vemos isso na figura a seguir:

Uma foto bonita e uma imagem esticada em comparação
A proporção da imagem é diferente da caixa que a contém e a imagem é esticada. (Visualização grande)

A solução

Nem sempre precisamos adicionar uma imagem de tamanho diferente quando a proporção da imagem não se alinha com a largura e a altura do elemento que a contém. Antes de mergulhar nas soluções CSS, quero mostrar como costumávamos fazer isso em aplicativos de edição de fotos:

Exemplo de uma imagem com as bordas superior e inferior cortadas em uma máscara
Primeiro, centralizamos a imagem verticalmente e, em seguida, recortamos uma máscara. Isso retém a proporção da imagem e evita que ela seja comprimida. (Visualização grande)

Agora que entendemos como isso funciona, vamos ver como isso funciona no navegador. ( Alerta de spoiler: é mais fácil! )

object-fit CSS

A propriedade object-fit define como o conteúdo de um elemento substituído, como img ou video , deve ser redimensionado para caber em seu contêiner. O valor padrão para object-fit é fill , o que pode resultar em uma imagem sendo espremida ou esticada.

Vamos analisar os valores possíveis.

Mais depois do salto! Continue lendo abaixo ↓

Valores possíveis para object-fit

object-fit: contain

Nesse caso, a imagem será redimensionada para se ajustar à proporção de seu contêiner. Se a proporção da imagem não corresponder à do contêiner, ela será colocada em letterbox.

ajuste de objeto: conter
Ao usar object-fit: contain , a imagem será colocada em letterbox ou redimensionada de acordo. (Visualização grande)

object-fit: cover

Aqui, a imagem também será redimensionada para caber na proporção de seu contêiner e, se a proporção da imagem não corresponder à do contêiner, ela será cortada para caber.

ajuste ao objeto: capa
Ao usar object-fit: cover , a imagem será cortada para caber ou redimensionada de acordo. (Visualização grande)

object-fit: fill

Com isso, a imagem será redimensionada para caber na proporção de seu contêiner e, se a proporção da imagem não corresponder à do contêiner, ela será espremida ou esticada. Nós não queremos isso.

ajuste de objeto: preencher
Ao usar object-fit: fill , a imagem será comprimida, esticada ou redimensionada de acordo. (Visualização grande)

object-fit: none

Nesse caso, a imagem não será redimensionada, nem esticada nem espremida. Funciona como o valor da cover , mas não respeita a proporção do seu contêiner.

ajuste de objeto: nenhum
Ao usar object-fit: none , a imagem não será redimensionada se suas dimensões não forem as mesmas. (Visualização grande)

Além de object-fit , temos também a propriedade object-position , que é responsável por posicionar uma imagem dentro de seu container.

Valores Possíveis para object-position

A propriedade object-position funciona de forma semelhante à propriedade background-position CSS:

centro da posição do objeto, esquerda, direita
Na maioria das vezes, o valor padrão é usado (ou seja, `center` ou `50% 50%`). (Visualização grande)

As palavras-chave top e bottom também funcionam quando a proporção da caixa que contém é verticalmente maior:

posição do objeto superior e inferior
Comparando object-position: top (esquerda) e object-position: bottom (direita). (Visualização grande)

background-size CSS

Com background-size , a primeira diferença é que estamos lidando com o background, não com um elemento HTML ( img ).

Valores possíveis para background-size

Os valores possíveis para background-size são auto , contain e cover .

background-size: auto

Com auto , a imagem permanecerá em seu tamanho padrão:

tamanho de fundo: automático
Lembre-se de que o tamanho padrão às vezes pode resultar em uma imagem borrada (se for muito pequena). (Visualização grande)

background-size: cover

Aqui, a imagem será redimensionada para caber no contêiner. Se as proporções não forem as mesmas, a imagem será mascarada para caber.

tamanho do fundo: capa
Ao usar background-size: cover , certifique-se de considerar as proporções de uma imagem. (Visualização grande)

background-size: contain

Nesse caso, a imagem será redimensionada para caber no contêiner. Se as proporções estiverem desativadas, a imagem será colocada em letterbox, conforme mostrado no próximo exemplo:

tamanho do plano de fundo: conter
background-size: contain container redimensiona a imagem para caber no container. (Visualização grande)

Quanto ao background-position , é semelhante a como o object-position funciona. A única diferença é que a posição padrão de object-position é diferente daquela de background-position .

Quando não usar object-fit ou background-size

Se o elemento ou a imagem tiver uma altura fixa e tiver background-size: cover ou object-fit: cover aplicada a ele, haverá um ponto em que a imagem ficará muito larga, perdendo detalhes importantes que podem afetar a o usuário percebe a imagem.

Considere o seguinte exemplo em que a imagem recebe uma altura fixa:

 .card__thumb { height: 220px; }
Um exemplo em que uma imagem é muito larga porque tem uma altura fixa e o recipiente do cartão é muito largo
A imagem mostrada à direita é muito larga porque tem uma altura fixa enquanto o recipiente do cartão é muito largo. (Visualização grande)

Se o recipiente do cartão for muito largo, resultará no que vemos à direita (uma imagem muito larga). Isso ocorre porque não estamos especificando uma proporção.

Há apenas uma das duas correções para isso. A primeira é usar o hack de preenchimento para criar uma proporção intrínseca.

 .card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

A segunda correção é usar a nova propriedade CSS aspect-ratio . Usando-o, podemos fazer o seguinte:

 .card__thumb img { aspect-ratio: 4 / 3; }

Nota : Eu já escrevi sobre a propriedade aspect-ratio em detalhes caso você queira aprender sobre ela: “Vamos aprender sobre a relação de aspecto em CSS”.

Casos de uso e exemplos

Avatares de usuário

Um caso de uso perfeito para object-fit: cover são os avatares dos usuários. A proporção permitida para um avatar geralmente é quadrada. Colocar uma imagem em um recipiente quadrado pode distorcer a imagem.

Um avatar de usuário sem ajuste de objeto e com ajuste de objeto: capa
Uma comparação de um avatar de usuário sem object-fit e com object-fit: cover . (Visualização grande)
 .c-avatar { object-fit: cover; }

Lista de logotipos

Listar os clientes de uma empresa é importante. Muitas vezes, usaremos logotipos para essa finalidade. Como os logotipos terão tamanhos diferentes, precisamos redimensioná-los sem distorcê-los.

Felizmente, object-fit: contain é uma boa solução para isso.

 .logo__img { width: 150px; height: 80px; object-fit: contain; }
Uma lista de logotipos: Airbnb, Domino's Pizza, Apple Pay, Amazon
Usar object-fit: contain pode nos ajudar a redimensionar os logotipos dos clientes sem distorcê-los. (Visualização grande)

Miniatura do artigo

Este é um caso de uso muito comum. O contêiner de uma miniatura de artigo pode nem sempre ter uma imagem com a mesma proporção. Esse problema deve ser corrigido pelo sistema de gerenciamento de conteúdo (CMS) em primeiro lugar, mas nem sempre é.

 .article__thumb { object-fit: cover; }
Miniatura do artigo
Ajustando miniaturas de artigos com um pouco de ajuda de object-fit: cover . (Visualização grande)

Antecedentes do Herói

Nesse caso de uso, a decisão de usar um elemento img ou um plano de fundo CSS dependerá do seguinte:

  • A imagem é importante? Se o CSS estiver desabilitado por algum motivo, queremos que o usuário veja a imagem?
  • Ou o propósito da imagem é meramente decorativo?

Com base em nossa resposta, podemos decidir qual recurso usar. Se a imagem for importante :

Caso de uso com um plano de fundo herói
Vamos supor que a imagem seja importante, porque é um site relacionado a comida. (Visualização grande)
 <section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
 .hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

Se a imagem for decorativa , podemos usar background-image :

 .hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }

O CSS é mais curto neste caso. Certifique-se de que qualquer texto colocado sobre a imagem seja legível e acessível.

Adicionando um plano de fundo a uma imagem com object-fit: contain

Você sabia que pode adicionar uma cor de fundo a img ? Nós nos beneficiaríamos disso ao usar também object-fit: contain .

No exemplo abaixo, temos uma grade de imagens. Quando as proporções da imagem e do contêiner forem diferentes, a cor de fundo aparecerá.

 img { object-fit: contain; background-color: #def4fd; }
Adicionando uma cor de fundo a uma imagem com ajuste de objeto: conter
Podemos usar object-fit: contain para adicionar uma cor de fundo a uma imagem. (Visualização grande)

Elemento de vídeo

Você já precisou de um video como plano de fundo? Nesse caso, você provavelmente queria que ele ocupasse toda a largura e altura de seu pai.

 .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
Uma figura em que o vídeo não cobre o plano de fundo do herói
O valor object-fit padrão para o elemento de video é contain . Como você pode ver aqui, o vídeo não cobre o plano de fundo do herói, embora tenha position: absolute , width: 100% e height: 100% . (Visualização grande)

Para que ele cubra totalmente a largura e a altura de seu pai, precisamos substituir o valor object-fit padrão:

 .hero__video { /* other styles */ object-fit: cover; }
Uma figura em que o vídeo cobre toda a largura e altura de seu pai.
Agora o vídeo cobre toda a largura e altura de seu pai. (Visualização grande)

Conclusão

Como vimos, tanto object-fit quanto background-size são muito úteis para lidar com diferentes proporções de imagem. Nem sempre teremos controle sobre a definição das dimensões perfeitas para cada imagem, e é aí que esses dois recursos CSS brilham.

Um lembrete amigável sobre as implicações de acessibilidade de escolher entre um elemento img e um plano de fundo CSS: Se a imagem for puramente decorativa, escolha um plano de fundo CSS. Caso contrário, uma img é mais adequada.

Espero que você tenha achado este artigo útil. Obrigado por ler.