Um mergulho profundo no ajuste do objeto e no tamanho do plano de fundo em CSS
Publicados: 2022-03-10object-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:
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:
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:
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.
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.
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.
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.
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.
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:
As palavras-chave top
e bottom
também funcionam quando a proporção da caixa que contém é verticalmente maior:
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:
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.
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:
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; }
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.
.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; }
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; }
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 :
<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; }
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%; }
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; }
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.