
Perambulando pelos padrões da W3C, encontrei uma coisa bem interessante na especificação de imagens CSS3 — a mesma que define os gradientes. Trata-se do modo de definição de tamanhos para imagens com as propriedades CSS object-fit
e object-position
, o que achei bastante útil principalmente para quando precisamos construir miniaturas (thumbnails) para visualizar imagens. Abaixo temos uma mini galeria com algumas imagens.
OBS.: Para visualizar os resultados experimentados neste post, é preciso utilizar um navegador baseado na engine do Blink (Google Chrome ou Opera) — caso contrário, não fará o menos sentido ler este material sem ver os resultados.








As miniaturas acima foram compostas apenas com o elemento <img>
, ou seja, não foi preciso fazer uso de um elemento pai para servir de empacotador para a imagem — coisa que é muito comum na construção de miniaturas, costuma-se utilizar uma <div>
com overflow: hidden
e fazer o redimensionamento da imagem para acompanhar o tamanho da <div>
.
<!-- Isso -->
<img class="galeria-img" src="einstein.jpg" alt="Einstein" />
<!-- Não isso -->
<div class="galeria-thumb">
<img class="galeria-img" src="einstein.jpg" alt="Einstein" />
</div>
Note que as quatro primeiras imagens são a mesma imagem, assim como as quatro últimas. A imagem do Einstein tem uma orientação de retrato (altura maior que largura), enquanto que a imagem do Chico Science tem uma orientação de paisagem (largura maior que altura).
object-fit
Cada uma das quatro ocorrências dessas imagens tem um comportamento diferente. Esse comportamento é definido através da propriedade object-fit
, e com o uso dessa propriedade, fica visível que há uma separação entre o elemento invólucro (pai) e o conteúdo (bitmap) da imagem — o que já dá para perceber se utilizarmos a propriedade padding
em uma imagem.
Então, o elemento <img>
não é apenas um elemento, afinal de contas; mas pelo menos dois — assim como a maioria dos elementos HTML, afinal, a Shadow DOM está aí.
A propriedade object-fit
define como o conteúdo da imagem é apresentado em relação ao seu elemento invólucro (elemento pai), e pode ter seu valor igual a fill
, none
, cover
, contain
ou scale-down
. Para notar as diferenças do uso dessa propriedade, é necessário que a imagem em questão tenha altura e largura definidas. No nosso exemplo acima temos ambas as dimensões com 140 pixels:
.galeria-img {
width: 140px;
height: 140px;
}
Agora, vamos ao que interessa.
fill
Este é o valor padrão para object-fit
. Para uma imagem com com altura e largura definidas, sua forma será achatada se a proporção resultante for diferente da original (comportamento padrão das imagens até então).


fill
.galeria-img {
width: 140px;
height: 140px;
object-fit: fill;
}
none
Com none
, não é realizado nenhum processamento na imagem, mas ela será “cropada” (crop) pelas dimensões definidas, ou seja, será renderizada com seu bitmap inalterado, porém cortado. Com um exemplo fica mais fácil de entender:


none
.galeria-img {
width: 140px;
height: 140px;
object-fit: none;
}
Agora, vejamos o que acontece quando uma das dimensões definidas excede sua correspondente original:


none
.galeria-img {
width: 220px;
height: 140px;
object-fit: none;
}
Como dito, nenhum processamento foi feito na imagem, e ela mantém seu tamanho original. Pode-se perceber também que, nesses dois exemplos, a imagem resultante foi posicionada de forma centralizada. Veremos isso mais adiante com a propriedade object-position
.
cover
Igualmente a none
, mantém a proporção original da imagem, porém faz um redimensionamento na imagem para que esta possa preencher toda a área definida pelas dimensões especificadas. A seguir temos o mesmo exemplo do caso anterior, a única coisa que muda é o valor de object-fit
para cover
.


cover
.galeria-img {
width: 220px;
height: 140px;
object-fit: cover;
}
contain
Mantém a proporção original como em cover
, mas faz um redimensionamento na imagem de modo que esta não seja cortada e seja mostrada completamente dentro da área definida pelas dimensões especificadas.


contain
.galeria-img {
width: 140px;
height: 140px;
object-fit: contain;
}
scale-down
Esse é um valor que pode causar um pouco de confusão. Ele fará com que a imagem se comporte de dois jeitos diferentes, dependendo do seu tamanho. scale-down
irá sempre se comportar igual a none
ou contain
. O comportamento resultante sempre será o que representar um menor tamanho de imagem desenhada — e isso dependerá das dimensões originais da imagem e das dimensões definidas para o elemento <img>
. De novo, com um exemplo fica mais fácil:


scale-down

scale-down
.einstein-fit-1 {
width: 120px;
height: 250px;
object-fit: scale-down;
}
.einstein-fit-2 {
width: 200px;
height: 250px;
object-fit: scale-down;
}
Podemos perceber que nas duas imagens temos a mesma altura, e apenas mudamos a largura de um para o outro. No primeiro caso, scale-down
se comporta como contain
, pois none
resultaria numa imagem maior. Já no segundo caso, temos o oposto, scale-down
se comporta como none
, pois contain
resultaria numa imagem maior. Simples, não é?
object-position
O propósito de object-position
é bem simples: posicionar o conteúdo da imagem dentro do emento <img>
. O seu valor é definido exatamente da mesma maneira que a propriedade background-position
. No exemplo a seguir temos imagens definidas com object-fit: cover
e modificamos seu alinhamento vertical.

cover

cover
no topo
cover
na base.einstein-fit-1 {
object-fit: cover;
object-position: 50% 50%; /* valor padrão */
}
.einstein-fit-2 {
object-fit: cover;
object-position: 50% 0%; /* alinhada ao topo */
}
.einstein-fit-3 {
object-fit: cover;
object-position: 50% 100%; /* alinhada à base */
}
Agora, para ilustrar o alinhamento horizontal, no exemplo a seguir temos imagens definidas com object-fit: contain
.

contain

contain
no topo
contain
na base.einstein-fit-1 {
object-fit: contain;
object-position: 50% 50%; /* valor padrão */
}
.einstein-fit-2 {
object-fit: contain;
object-position: 0% 50%; /* alinhada à esquerda */
}
.einstein-fit-3 {
object-fit: contain;
object-position: 100% 50%; /* alinhada à direita */
}
Claro que também é possível utilizar outras unidades como px
, em
, etc. e valores negativos também.
Ah, e mais uma coisinha…
As propriedades object-fit
e object-position
podem ser utilizadas também no elemento <video>
, nos possibilitando realizar exatamente as mesmas configurações de estilos tanto para imagens quanto para vídeos.
Suporte | |||||
---|---|---|---|---|---|
object-fit | 31 | -- | -- | -- | 19 |
object-position | 31 | -- | -- | -- | 19 |
Informações segundo o caniuse. Apenas o Google Chrome e o Opera dão suporte atualmente (logicamente, agora que o Opera também usa o Blink).