Como posso preencher um div com uma imagem mantendo-a proporcional?


120

Eu encontrei este tópico - Como você estica uma imagem para preencher um <div> enquanto mantém a proporção da imagem? - isso não é exatamente o que eu quero.

Eu tenho um div com um determinado tamanho e uma imagem dentro dele. Eu quero sempre preencher o div com a imagem, independentemente se a imagem é paisagem ou retrato. E não importa se a imagem é cortada (o próprio div tem overflow oculto).

Então se a imagem é retrato eu quero widthque seja 100%e height:autoassim fica na proporção. Se a imagem for paisagem eu quero heightser 100%e ser width to beauto`. Parece complicado, certo?

<div class="container">
   <img src="some-image.jpg" alt="Could be portrait or landscape"/>
</div>

Como não sei como fazer, simplesmente criei uma imagem rápida do que quero dizer. Não consigo nem descrever corretamente.

insira a descrição da imagem aqui

Então, acho que não sou o primeiro a perguntar isso. No entanto, não consegui encontrar uma solução para isso. Talvez haja uma nova maneira CSS3 de fazer isso - estou pensando no flex-box. Qualquer ideia? Talvez seja ainda mais fácil do que eu esperava?


Por que você quer usar o css3 quando você ainda pode fazer isso facilmente com javascript? Vá com js matey ..
GautamJeyaraman

1
Não testado, mas você pode tentar definir a altura mínima e largura mínima para 100%? Isso deve pelo menos preencher a caixa e mantê-la em proporção
chrisbulmer

Respostas:


150

Se eu entendi corretamente o que você quer, você pode deixar os atributos de largura e altura fora da imagem para manter a proporção e usar o flexbox para fazer a centralização para você.

.fill {
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden
}
.fill img {
    flex-shrink: 0;
    min-width: 100%;
    min-height: 100%
}
<div class="fill">
    <img src="https://lorempizza.com/320/240" alt="" />
</div>

JSFiddle aqui

Eu testei isso com sucesso no IE9, Chrome 31 e Opera 18. Mas nenhum outro navegador foi testado. Como sempre, você deve considerar seus requisitos de suporte específicos.


No IE9, a imagem não é centralizada verticalmente ou horizontalmente com este método, ela é alinhada ao topo e à esquerda. i59.tinypic.com/ouo77s.png
Mike Kormendy

1
Isso tem um problema no iPad, parece que o safari aumenta a imagem em 100% de sua altura, mas não mantém a propriedade de largura mínima.
Sean

14
Isso parece dimensionar pequenas imagens para preencher, mas não para baixo para caber. Pelo menos quando eu uso uma imagem grande, ela mostra apenas uma pequena parte dela.
Johncl

12
Para ter uma imagem grande reduzida para caber, usei o seguinte na imagem:.fill img { min-height:100%; min-width: 100%; object-fit: cover; }
Peter G

super-herói! : D
Garis M Suero

47

É um pouco tarde, mas acabei de ter o mesmo problema e finalmente resolvi-o com a ajuda de outra postagem stackoverflow ( https://stackoverflow.com/a/29103071 ).

.img {
   object-fit: cover;
   width: 50px;
   height: 100px;
}

Espero que isso ainda ajude alguém.

Obs .: Também funciona junto com as propriedades css max-height , max-width , min-width e min-height . É especialmente útil com o uso de unidades de comprimento como 100% ou 100vh / 100vw para preencher o contêiner ou toda a janela do navegador.


esta é uma solução para crossbrowser?
candlejack de

1
ajuste ao objeto: capa; funciona bem! Informações do navegador (não funciona no IE): css-tricks.com/almanac/properties/o/object-fit Solução alternativa para o IE: medium.com/@primozcigler/… A MS está trabalhando na implementação: developer.microsoft.com / en-us / microsoft-edge / platform / status /…
Kaah

Acho que adicionar uma object-positionregra a esta classe será útil aqui. Apenas uma nota lateral.
Taha Paksu

8

Uma pergunta antiga, mas que merece uma atualização, pois agora existe um caminho.

A resposta correta baseada em CSS é usar object-fit: cover, que funciona assim background-size: cover. O posicionamento seria cuidado pelo object-positionatributo, que é padronizado como centralização.

Mas não há suporte para ele em nenhum navegador IE / Edge ou Android <4.4.4. Além disso, object-positionnão é compatível com Safari, iOS ou OSX. Polyfills existem, imagens de ajuste de objeto parecem oferecer o melhor suporte.

Para obter mais detalhes sobre como a propriedade funciona, consulte o artigo de truques de CSS sobreobject-fit para obter uma explicação e uma demonstração.


8

Isso deve servir:

img {    
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
}

Funciona muito bem para mim, no meu caso eu apenas pedi para adicionar posição: absoluto e superior: 0, e também algum índice z
byroncorrales

7

Todas as respostas abaixo têm largura e altura fixas, o que torna a solução "não responsiva".

Para alcançar o resultado, mas manter a imagem responsiva, usei o seguinte:

  1. Dentro do contêiner coloque uma imagem GIF transparente com a proporção desejada
  2. Dê uma tag de imagem em linha de fundo css com a imagem que deseja redimensionar e cortar

HTML:

<div class="container">
    <img style="background-image: url("https://i.imgur.com/XOmNCwY.jpg");" src="img/blank.gif">
</div> 


.container img{
   width: 100%;
   height: auto;
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center;
}​

Usei background-image para todo o site da empresa de portfólio de design para que eu pudesse ter background-size: cover. Agora meu SEO de imagem está todo confuso porque as imagens de fundo não são reconhecidas pelo Google. Eu gostaria de ter codificado de outra maneira.
Alex Banman

5

Você pode conseguir isso usando as propriedades css flex. Por favor veja o código abaixo

.img-container {
  border: 2px solid red;
  justify-content: center;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  
}
.img-container .img-to-fit {
  flex: 1;
  height: 100%;
}
<div class="img-container">
  <img class="img-to-fit" src="https://images.pexels.com/photos/8633/nature-tree-green-pine.jpg" />
</div>


1
Isso funciona SOMENTE se você remover as propriedades de largura e altura, conforme aludido em algumas das outras respostas.
Chiwda

3

Considere usar background-size: cover(IE9 +) em conjunto com background-image. Para o IE8-, existe um polyfill .


Isso não requer background-url? Você pode elaborar mais? Isso pode funcionar com o <img src = "" /> conforme indicado na pergunta?
harsimranb

@harsimranb Claro, background-sizefaz sentido apenas com o background-imageespecificado também (atualizei minha resposta de acordo). Não se aplica a IMGelementos.
Marat Tanalin

Esta é a melhor resposta. É simples e tem um bom suporte ao navegador. Todas as outras soluções são muito complexas ou não funcionam no IE (9).
JoostS de

1

Experimente isto:

img {
  position: relative;
  left: 50%;
  min-width: 100%;
  min-height: 100%;
  transform: translateX(-50%);
}

Espero que isto ajude


1

Você pode usar div para fazer isso. sem tag img :) espero que isso ajude.

.img{
	width:100px;
	height:100px;
	background-image:url('http://www.mandalas.com/mandala/htdocs/images/Lrg_image_Pages/Flowers/Large_Orange_Lotus_8.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
.img1{
	width:100px;
	height:100px;
	background-image:url('https://images.freeimages.com/images/large-previews/9a4/large-pumpkin-1387927.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
<div class="img">	
</div>
<div class="img1">	
</div>


1

A única maneira de alcançar o cenário de "melhor caso" descrito foi colocando a imagem como plano de fundo:

<div class="container"></div>
.container {
    width: 150px;
    height: 100px;
    background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-position: 50% 50%;
}​

1

Aqui está uma resposta com suporte para uso do IE object-fitpara que você não perca proporção

Usando um snippet JS simples para detectar se o object-fité compatível e, em seguida, substituir o imgpor umsvg

//for browsers which doesn't support object-fit (you can use babel to transpile to ES5)

if ('objectFit' in document.documentElement.style === false) {
  document.addEventListener('DOMContentLoaded', () => {
    Array.prototype.forEach.call(document.querySelectorAll('img[data-object-fit]'), image => {
      (image.runtimeStyle || image.style).background = `url("${image.src}") no-repeat 50%/${image.currentStyle ? image.currentStyle['object-fit'] : image.getAttribute('data-object-fit')}`
      image.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='${image.width}' height='${image.height}'%3E%3C/svg%3E`
    })
  })
}
img {
  display: inline-flex;
  width: 175px;
  height: 175px;
  margin-right: 10px;
  border: 1px solid red
}

/*for browsers which support object fit */

[data-object-fit='cover'] {
  object-fit: cover
}

[data-object-fit='contain'] {
  object-fit: contain
}
<img data-object-fit='cover' src='//picsum.photos/1200/600' />
<img data-object-fit='contain' src='//picsum.photos/1200/600' />
<img src='//picsum.photos/1200/600' />


Observação: também existem alguns object-fitpolyfills por aí que object-fitfuncionam.

Aqui estão alguns exemplos:


0

Aqui você tem meu exemplo de trabalho. Eu usei um truque que é definir a imagem como plano de fundo do contêiner div com background-size: cover e background-position: center center

Coloquei a imagem com largura: 100% e opacidade: 0 tornando-a invisível. Observe que estou exibindo minha imagem apenas porque tenho um interesse especial em chamar o evento de clique filho.

Observe que embora eu esteja usando angular, é completamente irrelevante.

<div class="foto-item" ng-style="{'background-image':'url('+foto.path+')'}">
    <img class="materialboxed" ng-class="foto.picid" ng-src="{{foto.path}}" style="opacity: 0;filter: alpha(opacity=0);" width="100%" onclick="$('.materialboxed')/>
 </div>
<style>
.foto-item {
height: 75% !important;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow:hidden;
background-size: cover;
background-position: center center;
}
</style>

O resultado é aquele que você define como ideal em todos os casos


0

O CSS object-fit: covere object-position: left centeros valores de propriedade agora tratam desse problema.


0

.image-wrapper{
    width: 100px;
    height: 100px;
    border: 1px solid #ddd;
}
.image-wrapper img {
    object-fit: contain;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}
<div class="image-wrapper">
  <img src="">
</div>


-3

Basta corrigir a altura da imagem e fornecer largura = auto

img{
    height: 95vh;
    width: auto;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.