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.


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.


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


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 ..."  />

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/


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


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/


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();

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%);
}

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!


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;
}

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.


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;
}

2

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

repetição de fundo: redondo;


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.