Tamanho da imagem CSS, como preencher, não esticar?

415

Eu tenho uma imagem e quero definir uma largura e altura específicas (em pixels)

Mas se eu definir largura e altura usando css ( width:150px; height:100px), a imagem será esticada e poderá ser feia.

Como preencher imagens para um tamanho específico usando CSS e não esticá- lo?

Exemplo de imagem de preenchimento e alongamento:

Imagem original:

Original

Imagem esticada:

Esticado

Imagem preenchida:

Preenchidas

Observe que no exemplo de imagem preenchida acima: primeiro, a imagem é redimensionada para 150x255 (proporção mantida) e, em seguida, cortada para 150x100.

Mahdi Ghiasi
fonte
Tente apenas definir o widthe heightdevem ajustar de acordo
NewInTheBusiness
3
Ele estende a imagem. veja isso: jsfiddle.net/D7E3E
Mahdi Ghiasi
É preciso que uma parte da imagem não seja redimensionada!
Ali Ben Messaoud
3
Chris Coyier também tem algumas boas soluções para isso: css-tricks.com/perfect-full-page-background-image
ambiguousmouse
1
MUITO IMPORTANTE: essa é uma prática incrivelmente ruim para fins de SEO. Se você a estiver usando como imagem de fundo, funcionará bem, mas se quiser que a imagem seja encontrada pelo Google, ela NÃO será indexada se for apenas uma imagem de fundo.
precisa saber é o seguinte

Respostas:

395

Se você deseja usar a imagem como plano de fundo CSS, existe uma solução elegante. Basta usar coverou containna background-sizepropriedade CSS3.

.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%;
}
<div class="container"></div>

Embora covervocê tenha uma imagem em escala reduzida, containuma imagem em escala reduzida. Ambos preservarão a proporção de pixel.

http://jsfiddle.net/uTHqs/ (usando capa)

http://jsfiddle.net/HZ2FT/ (usando contêm)

Essa abordagem tem a vantagem de ser amigável com os displays Retina, de acordo com o guia rápido de Thomas Fuchs.

Vale ressaltar que o suporte ao navegador para ambos os atributos exclui o IE6-8.

Marcelo De Polli
fonte
1
Como você pode redimensionar a imagem exclusivamente no CSS, isso permite que você use uma imagem grande e reduza-a de acordo com a densidade de pixels de cada dispositivo usando consultas de mídia.
Marcelo De Polli
1
Você poderia explicar por que, neste caso, a posição do plano de fundo parece indicar a posição do centro da imagem em vez do canto superior esquerdo? É uma consequência do tamanho do plano de fundo: capa?
Matteo 01/03
1
o meu cobre apenas o DIV inteiro, expandindo a imagem. Não vejo a curva terminando.
SearchForKnowledge
3
Para que serve background-repeat: no-repeat;? Se a imagem cobrir seu contêiner, ela não se repetirá de qualquer maneira.
Lurkit 15/07/16
3
'background-position' também pode ser definido como 'center center'. por exemplo: .container {... background-position: center center; }
Leo Ribeiro
556

Você pode usar a propriedade css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Veja o exemplo aqui

Existe um polyfill para o IE: https://github.com/anselmh/object-fit

afonsoduarte
fonte
11
Interessante ver que isso também pode ser feito com imgtags (não apenas o background-imagemétodo descrito na resposta acima). Obrigado :)
Mahdi Ghiasi
44
Ao considerar isso como uma opção, lembre-se de que object-fit não há suporte para muitos navegadores .
Joshreesjones 19/09/2015
2
Infelizmente, background-sizeraramente é uma solução viável em meus projetos. É menos provável que você receba qualquer benefício de SEO e não pode fornecer uma tag ALT, legenda etc. para acompanhar a imagem, na qual você pode fornecer um contexto adicional para os leitores de tela.
Markus12
3
Isso é legal, mas não há suporte para o IE. Nenhum dos polyfills funciona mais.
Jake
3
Apenas usando object-fit: cover;faz. Muito obrigado
Luka
67

Aprimoramento na resposta acima por @afonsoduarte ( NÃO o aceito) .
no caso de você estar usando o bootstrap


Existem três diferenças:

  1. Fornecendo width:100%o estilo.
    Isso é útil se você estiver usando o bootstrap e desejar que a imagem estenda toda a largura disponível.

  2. A especificação da heightpropriedade é opcional. Você pode removê-la / mantê-la conforme necessário

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
    
  3. A propósito, NÃO há necessidade de fornecer os atributos heighte widthno imageelemento, pois eles serão substituídos pelo estilo.
    portanto, basta escrever algo assim.

    <img class="cover" src="url to img ..."  />
Hakan Fıstık
fonte
1
Exatamente o que eu estava procurando.
Francis lanthier 5/0518
1
Você precisa de um beijo!
Qin Wang
ajuste de objeto não funciona com o IE?
bgcode 8/01
1
é 2020, acho que é um bom momento para abandonar o IE
Hakan Fıstık
56

A única maneira real é ter um contêiner em torno de sua imagem e usar overflow:hidden:

HTML

<div class="container"><img src="ckk.jpg" /></div>

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

É difícil para o CSS fazer o que você deseja e centralizar a imagem; há uma correção rápida no jquery, como:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/

Dominic Green
fonte
1
Obrigado. funcionou, mas corta a imagem de cima . (veja isto: jsfiddle.net/x86Q7 ) Não há como cortar a imagem do centro ?
Mahdi Ghiasi
1
@MahdiGhiasi: Altere as propriedades superior e esquerda em .container img css !!
Ali Ben Messaoud
Posso definir a margin-topimagem por exemplo 50px(veja: jsfiddle.net/x86Q7/1 ), mas como cortá-la do centro real ? (Sem jQuery?)
Mahdi Ghiasi
2
Ahh pena não ver o seu comentário, mas eu adicionei o jquery só meter :)
Dominic Verde
1
Ótima solução! Para mim, o preenchimento vertical era mais importante que o horizontal, então eu apenas tive que alterar "width: 100%" para "height: 100%" para a classe '.container img'. Obrigado!
deebs
26

Solução CSS sem JS e sem imagem de plano de fundo:

Método 1 "margem automática" (IE8 + - NÃO FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Método 2 "transformar" (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

O método 2 pode ser usado para centralizar uma imagem em um contêiner de largura / altura fixo. Ambos podem transbordar - e se a imagem for menor que o contêiner, ela ainda será centralizada.

http://jsfiddle.net/5xjr05dt/3/

Método 3 "invólucro duplo" (IE8 + - NÃO FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Método 4 "invólucro duplo E imagem dupla" (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • O método 1 tem um suporte um pouco melhor - você precisa definir a largura OU a altura da imagem!
  • Com os prefixos, o método 2 também tem suporte decente (de ie9 para cima) - o método 2 não tem suporte no Opera mini!
  • O método 3 usa dois invólucros - pode estourar a largura E a altura.
  • O método 4 usa uma imagem dupla (uma como espaço reservado), o que fornece uma sobrecarga extra de largura de banda, mas suporte ainda melhor ao navegador.

Os métodos 1 e 3 parecem não funcionar com o Firefox

JT Houtenbos
fonte
Este é o único que realmente funciona (menos as soluções js). Obrigado!
Jake
É limitado a transbordar altura ou largura, mas uma solução interessante.
Jake
1
@ Jake - É possível estourar a largura E a altura com o método 2 acima - veja minha resposta atualizada com o violino extra.
JT Houtenbos
Sim. É definitivamente uma ótima resposta. Vou brincar um pouco mais com isso. Era um pouco peculiar para uma imagem maior que a mais alta que precisava ser responsiva, mas existem muitos aplicativos para isso.
Jake
1
@ Jake - Legal - Encontrei um terceiro método para fazer a centralização horizontal. Estendi esse método para também apoiar a centralização vertical. Vou postar minha adição como um terceiro método acima. Parece que é a prova do IE7 + (possivelmente ainda mais baixa). Aqui está a resposta original: stackoverflow.com/questions/3300660/…
JT Houtenbos
10

Outra solução é colocar a imagem em um recipiente com a largura e altura desejadas. Usando esse método, você não precisaria definir a imagem como imagem de plano de fundo de um elemento.

Em seguida, você pode fazer isso com uma imgtag e apenas definir uma largura e uma altura máxima no elemento.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

.imgContainer img {
    max-width: 100%;
    max-height: 100%;
}

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

Agora, quando você altera o tamanho do contêiner, a imagem aumenta automaticamente o máximo possível, sem sair dos limites ou distorcer.

Se você deseja centralizar a imagem na vertical e na horizontal, pode alterar o CSS do contêiner para:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Aqui está um JS Fiddle http://jsfiddle.net/9kUYC/2/

earl3s
fonte
Ela não é a mesma como a tampa em CSS, em que uma das dimensões resultantes é sempre além de 100% (ou igual em caso extremo)
Miroshko
Não, essa solução garante que ela nunca ultrapasse os 100%, e é disso que parte da pergunta se trata. Eles não querem que a imagem distorça ou cresça além das dimensões originais.
earl3s
3
A pergunta era "Como preencher" com um exemplo de imagem preenchida, que obviamente é cortada.
Miroshko
Mas e se você precisar que a imagem seja responsiva? Definir uma largura específica e altura não vai trabalho 😕
Ricardo Zea
2
Era o que eu precisava. Obrigado!
Nico Rodsevich 30/03/19
5

Partindo da resposta de @Dominic Green usando jQuery, aqui está uma solução que deve funcionar para imagens que são mais largas do que altas ou mais altas.

http://jsfiddle.net/grZLR/4/

Provavelmente existe uma maneira mais elegante de fazer o JavaScript, mas isso funciona.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();
ramdog
fonte
5
  • Não usando o plano de fundo css
  • Apenas 1 div para cortá-lo
  • Redimensionado para a largura mínima para manter a proporção correta
  • Cortar do centro (vertical e horizontalmente, você pode ajustá-lo com o topo, esquerda e transformação)

Tenha cuidado se estiver usando um tema ou algo assim, eles geralmente declaram img max-width em 100%. Você tem que fazer nenhum. Testá-lo :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}
dmegatool
fonte
Esta é a resposta que eu estava procurando.
Marcos Buarque
Isto é o que eu queria fazer por um longo tempo, obrigado;)
Boss COTIGA
4

Ajudei a criar um plug-in jQuery chamado Fillmore , que lida com os background-size: covernavegadores que o suportam e tem um calço para aqueles que não o fazem. Dê uma olhada!

Aidan Feldman
fonte
4

Eu acho que é muito tarde para esta resposta. De qualquer forma, espero que isso ajude alguém no futuro. Eu enfrentei o problema de posicionar os cartões em angular. Existem cartões exibidos para a matriz de eventos. Se a largura da imagem do evento for grande para o cartão, a imagem deverá ser mostrada cortando dos dois lados e com uma altura de 100%. Se a altura da imagem for longa, a parte inferior das imagens será cortada e a largura será de 100%. Aqui está a minha solução css pura para isso:

insira a descrição da imagem aqui

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}
Nodirabegimxonoyim
fonte
Não consigo entender como isso funciona, mas funciona. Você precisa posicionar a extensão absolutamente em cima: 0; direita: 0; embaixo: 0; esquerda: 0 dentro do pai relativamente posicionado para dimensioná-lo.
Mike
Obrigado pelo feedback, querido Mike, fico feliz se isso foi útil. Deseja que eu atualize a resposta com seu comentário?
Nodirabegimxonoyim
3

Tente algo assim: http://jsfiddle.net/D7E3E/4/

Usando um contêiner com estouro: hidden

EDIT: @Dominic Green me venceu.

woutr_be
fonte
Obrigado. funcionou, mas corta a imagem de cima . (veja isto: jsfiddle.net/x86Q7 ) Não há como cortar a imagem do centro ?
Mahdi Ghiasi
Pode ser um pouco difícil com CSS, este é o melhor que eu poderia vir acima com jsfiddle.net/D7E3E/5
woutr_be
Sim, para centralizá-lo corretamente, você deve usar o jQuery, pode ser muito mais fácil.
woutr_be
3

Isso preencherá as imagens em um tamanho específico, sem esticá-las ou cortá-las

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

/*Scale down will take the necessary specified space that is 150px x 100px without stretching the image*/
    object-fit:scale-down;
}
Manoj Selvin
fonte
2

Para ajustar a imagem em tela cheia, tente o seguinte:

repetição de fundo: redondo;

suyash1798
fonte
0
<div class="container">
     <img src="http://i.stack.imgur.com/2OrtT.jpg"/>
</div>

<style>
.container {
       width: 150px;
       height: 100px;
       overflow: hidden;
}
</style>
user3181614
fonte