CSS redimensiona a imagem e mantém a proporção

577

Estou trabalhando com imagens e me deparei com um problema com proporções.

<img src="big_image.jpg" width="900" height="600" alt="" />

Como você pode ver, heighte widthjá está especificado. Adicionei regra CSS para imagens:

img {
  max-width:500px;
}

Mas para big_image.jpg, eu recebo width=500e height=600. Como posso definir as imagens para serem redimensionadas, mantendo suas proporções.

moonvader
fonte

Respostas:

775

img {
  display: block;
  max-width:230px;
  max-height:95px;
  width: auto;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

Isso reduzirá a imagem se ela for muito grande para a área especificada (como desvantagem, ela não aumentará a imagem).

setec
fonte
11
Existe uma versão disso que ampliará imagens para caber no contêiner também? Eu tentei o max-width / max-height como números com largura / altura como auto, mas como setec disse acima, ele não ampliará a imagem. Eu tentei usar min-width / min-height também. Eu simplesmente não consigo acertar a combinação. Eu simplesmente quero que qualquer imagem que eu tenha que colocar neste contêiner, ela será exibida no tamanho máximo possível sem alterar a proporção, independentemente de envolver a redução ou o aumento da imagem para isso.
precisa
7
Parece que exibe: block não é mais necessário.
actimel
3
Observe que a pergunta era sobre uma <img>que inclui largura e altura e acho que isso significa que você precisa usar !importantpara contornar as informações de largura / altura da tag.
Alexis Wilke
18
As regras CSS do @AlexisWilke substituem os atributos html. !importantNão é necessário.
Jargs
5
Usá-lo no Chrome, não está funcionando para mim, mesmo com! Important #
Ray Ray
266

Eu lutei bastante com esse problema e, finalmente, cheguei a esta solução simples:

object-fit: cover;
width: 100%;
height: 250px;

Você pode ajustar a largura e a altura para atender às suas necessidades, e a propriedade de ajuste do objeto fará o corte para você.

Felicidades.

Théo T. Carranza
fonte
44
object-fité fantástico, ótima dica! Existem algumas bibliotecas finas de polyfill se alguém estiver se perguntando sobre a compatibilidade com o IE.
sofly 11/10/16
7
Lovely, tenha em mente que esta não funciona para o IE embora
guival
1
Não é viável no SAMSUNG Signage Display WebApps.
Mar
3
Melhor solução disponível
Cynthia Sanchez
10
Você também pode usar object-fit: containe especificar uma largura ou altura!
Broper 02/12/19
236

As soluções abaixo permitirão o aumento e redução da imagem , dependendo da largura da caixa pai.

Todas as imagens têm um contêiner pai com uma largura fixa apenas para fins de demonstração . Na produção, essa será a largura da caixa pai.

Melhores práticas (2018):

Esta solução informa ao navegador para renderizar a imagem com a largura máxima disponível e ajustar a altura como uma porcentagem dessa largura.

.parent {
  width: 100px;
}

img {
  display: block;
  width: 100%;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
  <img width="400" height="400" src="https://placehold.it/400x400">
</div>

Solução mais sofisticada:

Com a solução mais sofisticada, você poderá cortar a imagem independentemente do tamanho e adicionar uma cor de fundo para compensar o corte.

.parent {
  width: 100px;
}

.container {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  overflow: hidden;
  padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}

.container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
  <div class="container">
    <img width="640" height="220" src="https://placehold.it/640x220">
  </div>
</div>

Para a linha que especifica o preenchimento, é necessário calcular a proporção da imagem, por exemplo:

640px (w) = 100%
220px (h) = ?

640/220 = 2.909
100/2.909 = 34.37%

Portanto, preenchimento superior = 34,37%.

Aternus
fonte
1
Está funcionando, mas deve ter largura máxima: 100% em vez de largura na maioria dos usos.
Dudeist
Eu não acho que !importanté necessário aqui.
Flimm
1
Com o pai definido como 100px. Como isso funcionará responsivamente?
Remi
@Remi é para fins de demonstração. Eu adicionei um esclarecimento ao topo da resposta.
Aternus
O @Flimm foi usado anteriormente para problemas de compatibilidade, em 2016 isso não é mais necessário.
Aternus
64

A propriedade de tamanho do plano de fundo é, por exemplo,> = 9 apenas, mas se estiver tudo bem com você, você pode usar uma div com background-imagee definir background-size: contain:

div.image{
    background-image: url("your/url/here");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

Agora você pode simplesmente definir o tamanho do seu div para o que quiser e não apenas a imagem manterá sua proporção, como também será centralizada vertical e horizontalmente dentro do div. Apenas não esqueça de definir os tamanhos no css, já que divs não tem o atributo width / height na própria tag.

Essa abordagem é diferente da resposta setecs, usando isso, a área da imagem será constante e definida por você (deixando espaços vazios horizontal ou verticalmente, dependendo do tamanho da div e da proporção da imagem), enquanto a resposta setecs fornecerá uma caixa exatamente tamanho da imagem dimensionada (sem espaços vazios).

Edit: De acordo com a documentação de tamanho de plano de fundo MDN, você pode simular a propriedade de tamanho de plano de fundo no IE8 usando uma declaração de filtro proprietária:

Embora o Internet Explorer 8 não suporte a propriedade tamanho do plano de fundo, é possível emular algumas de suas funcionalidades usando a função -ms-filter não padrão:

-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
Hoffmann
fonte
2
finalmente, uma solução apenas CSS para maximizar uma imagem, mantendo sua proporção, obrigado. Sorte que o IE anterior ao 9 seja cada vez menos importante.
HumanidadeANDpeace
2
Ótima solução, obrigado! Observe também que você pode substituir 'conter' por 'cover' se você quiser encher a div completamente e cortar pixels extras que não cabem a relação
mbritto
Essa deve ser a resposta correta. Eu amo essa solução. Mantém suas proporções e é fácil de entender.
skolind
1
Embora essa seja uma resposta correta programaticamente, se uma imagem "importa" dessa maneira, você não tem atributos img; portanto, está matando o SEO.
fat_mike
Ótimo! Foi a única dessas soluções que funcionou para imagens retrato e paisagem, bem como para contêineres retrato e paisagem da imagem (por exemplo, variando de acordo com o tamanho da janela) em todas as 4 combinações e também no IE11, o que parecia bastante um requerimento. Obrigado!
Cupiqi09 17/10/19
53

Muito parecido com algumas respostas aqui, mas no meu caso eu tinha imagens que às vezes eram mais altas, às vezes maiores.

Esse estilo funcionou como um encanto para garantir que todas as imagens usem todo o espaço disponível, mantenha a proporção e não corte:

.img {
   object-fit: contain;
   max-width: 100%;
   max-height: 100%;
   width: auto;
   height: auto;
}
Moisés
fonte
object-fitfunciona para mim funciona em todos os navegadores?
Murtuza Zabuawala
Existe .imguma classe nos pais ou na imagem? Você poderia criar um jsfiddle com exemplo para imagens retrato e paisagem?
Design by Adrian
19

Remova a propriedade "height".

<img src="big_image.jpg" width="900" alt=""/>

Ao especificar ambos, você está alterando a proporção da imagem. Apenas definir um redimensionará, mas preservará a proporção.

Opcionalmente, para restringir as sobredimensionamentos:

<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
el Dude
fonte
eu não posso fazê-lo para todas as imagens - há muitas imagens já colocados em muitos arquivos html
moonvader
2
Está bem. tente img {largura máxima: 500 px; altura: auto; max-height: 600px;}
el Dude
1
Informações úteis como esse comentário devem ser adicionadas à sua postagem. Dessa forma, podemos ver imediatamente o que você criou.
Bram Vanroy
2
A desvantagem de omitir o heightatributo na imgtag é que o navegador não pode calcular quanto espaço a imagem ocupará antes de fazer o download da imagem. Isso torna a página mais lenta para renderizar e pode levar a mais "pulos".
Flimm 02/03
11

Basta adicionar isso ao seu css, ele diminuirá e expandirá automaticamente mantendo a proporção original.

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Mark Bax
fonte
2
Esta é a mesma resposta que a da setec , exceto usando em 100%vez de um valor específico de pixel.
Flimm
5
display: block;é desnecessário.
Flimm
Isso é perfeito e trabalha com imagens de qualquer tamanho e proporção
Le Droid
8

Não existe uma maneira padrão de preservar a proporção para imagens com width, heighte max-widthespecificadas juntas.

Portanto, somos forçados a especificar widthe heightevitar "pulos" na página durante o carregamento de imagens, ou a usar max-widthe não especificar dimensões para as imagens.

Especificar apenas width(sem height) normalmente não faz muito sentido, mas você pode tentar substituir o heightatributo HTML adicionando uma regra como IMG {height: auto; }na sua folha de estilo.

Veja também o bug relacionado do Firefox 392261 .

Marat Tanalin
fonte
obrigado, funciona em versões modernas do IE, Opera, FF e Chrome. Eu preciso de algum tempo para testá-lo com outros navegadores.
moonvader
7
Não use !importantem CSS. É um hack que acabará voltando para assombrá-lo.
Automatico
1
Você nem precisa !importantaqui.
Flimm
8

Aqui está uma solução:

img {
   width: 100%;
   height: auto;
   object-fit: cover;
}

Isso garantirá que a imagem sempre cubra todo o pai (diminuindo e diminuindo a escala) e mantendo a mesma proporção.

Thomas Carlton
fonte
5

Defina a classe CSS da sua tag de contêiner de imagem para image-class:

<div class="image-full"></div>

e adicione isso a sua folha de estilo CSS.

.image-full {
    background: url(...some image...) no-repeat;
    background-size: cover;
    background-position: center center;
}
Aleksandar Toplek
fonte
5

Para manter uma imagem responsiva e ainda impor a imagem a uma determinada proporção, você pode fazer o seguinte:

HTML:

<div class="ratio2-1">
   <img src="../image.png" alt="image">
</div>

E SCSS:

.ratio2-1 {
  overflow: hidden;
  position: relative;

  &:before {
    content: '';
    display: block;
    padding-top: 50%; // ratio 2:1
  }

  img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
  }
}

Isso pode ser usado para impor uma certa proporção, independentemente do tamanho da imagem que os autores carregam.

Obrigado a @Kseso em http://codepen.io/Kseso/pen/bfdhg . Verifique este URL para obter mais proporções e um exemplo de trabalho.

Remi
fonte
Eu gosto disso, pois trabalha com círculos / border-radius. Mas, infelizmente, ele corta a imagem e não se sai tão bem ao fazer uma borda para a imagem na div, tanto quanto eu tentei.
Jake
4

Para forçar a imagem que caiba no tamanho exato, você não precisa escrever muitos códigos. É tão simples

img{
    width: 200px;
    height: auto;
    object-fit: contain; /* Fit logo in the image size */
        -o-object-fit: contain; /* Fit logo fro opera browser */
    object-position: top; /* Set logo position */
        -o-object-position: top; /* Logo position for opera browser */
    }
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">

aislamfaisal
fonte
4

https://jsfiddle.net/sot2qgj6/3/

Aqui está a resposta se você deseja colocar uma imagem com porcentagem fixa de largura , mas não pixel fixo de largura .

E isso será útil ao lidar com diferentes tamanhos de tela .

Os truques são

  1. Usando padding-toppara definir a altura da largura.
  2. Usando position: absolutepara colocar a imagem no espaço de preenchimento.
  3. Usando max-height and max-widthpara garantir que a imagem não ultrapasse o elemento pai.
  4. usando display:block and margin: autopara centralizar a imagem.

Também comentei a maioria dos truques dentro do violino.


Também encontro outras maneiras de fazer isso acontecer. Não haverá imagem real em html, então eu pessoalmente prefiro a resposta principal quando preciso do elemento "img" em html.

css simples usando o plano de fundo http://jsfiddle.net/4660s79h/2/

imagem de fundo com a palavra no topo http://jsfiddle.net/4660s79h/1/

o conceito de usar posição absoluta é daqui http://www.w3schools.com/howto/howto_css_aspect_ratio.asp

Choco Li
fonte
Isso não funciona se "altura e largura já estiverem especificadas", conforme mencionado na pergunta original. Há momentos em que você deseja forçar a largura e a altura e aumentar / diminuir a imagem de acordo com a proporção.
Design by Adrian
3

Você pode usar isto:

img { 
    width: 500px; 
    height: 600px; 
    object-fit: contain; 
    position: relative; 
    top: 50%; 
    transform: translateY(-50%); 
}
user3334941
fonte
2

Você pode criar uma div como esta:

<div class="image" style="background-image:url('/to/your/image')"></div>

E use este css para estilizá-lo:

height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover
Chun Yang
fonte
Isso aumentará a div para 100% de largura, mas não manterá a proporção da imagem.
David Ball
Você tentou? Eu consegui trabalhar jsfiddle.net/zuysj22w . Você pode mostrar o seu caso? @DavidBall
Chun Yang
Esta é uma solução semelhante à resposta de Hoffmann .
Flimm
2

Sugiro que, para uma abordagem responsiva, a melhor prática seja usar as unidades Viewport e os atributos min / max da seguinte maneira:

img{
  display: block;
  width: 12vw;
  height:12vw;
  max-width:100%;
  min-width:100px;
  min-height:100px;
  object-fit:contain;
}
acena
fonte
1

Isso reduzirá a imagem se ela for muito grande para a área especificada (como desvantagem, ela não aumentará a imagem).

A solução da setec é adequada para "Reduzir para caber" no modo automático. Mas, para otimizar a EXPANDIR para caber no modo 'automático', você precisa primeiro colocar a imagem recebida em um ID de temperatura. Verifique se ela pode ser expandida em altura ou largura (dependendo da razão de aspecto em relação à proporção de seu bloco de exibição),

$(".temp_image").attr("src","str.jpg" ).load(function() { 
    // callback to get actual size of received image 

    // define to expand image in Height 
    if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
        $(".image").css('height', max_height_of_box);
        $(".image").css('width',' auto');
    } else { 
        // define to expand image in Width
        $(".image").css('width' ,max_width_of_box);
        $(".image").css('height','auto');
    }
    //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
    $(".image").attr("src","str.jpg");
});

Essa abordagem é útil quando as imagens recebidas são menores que a caixa de exibição. Você deve salvá-los em seu servidor no tamanho Original Pequeno, em vez da versão expandida, para preencher a Caixa de exibição Maior e economizar em tamanho e largura de banda.

Yselection Rajeev Shukla
fonte
Embora a pergunta não tenha sido explicada, acho que o OP implicava fortemente que ele estava procurando uma solução somente para CSS.
Flimm
0

img {
  max-width: 80px; /* Also works with percentage value like 100% */
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">

<p>Let's say the author of the HTML deliberately wants
  the height to be half the value of the width,
  this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">

Flimm
fonte
0

Que tal usar um pseudo-elemento para alinhamento vertical? Este código a menos é para um carrossel, mas acho que funciona em todos os contêineres de tamanho fixo. Ele mantém a proporção e insere @ barras cinza-escuras na parte superior / inferior ou esquerda / gravação para a dimensão mais curta. Enquanto isso, a imagem é centralizada horizontalmente pelo alinhamento do texto e verticalmente pelo pseudo-elemento.

    > li {
      float: left;
      overflow: hidden;
      background-color: @gray-dark;
      text-align: center;

      > a img,
      > img {
        display: inline-block;
        max-height: 100%;
        max-width: 100%;
        width: auto;
        height: auto;
        margin: auto;
        text-align: center;
      }

      // Add pseudo element for vertical alignment of inline (img)
      &:before {
        content: "";
        height: 100%;
        display: inline-block;
        vertical-align: middle;
      }
    }
Paul Bormans
fonte
0

Apresentação em tela cheia:

img[data-attribute] {height: 100vh;}

Lembre-se de que, se a altura da porta de visualização for maior que a imagem, a imagem degradará naturalmente em relação à diferença.

John
fonte
-1

Penso, finalmente, que esta é a melhor solução, fácil e simples :

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Você sabe
fonte
1
Você poderia explicar brevemente por que essa solução ajuda? (Apenas uma frase é suficiente.)
Aenadon
Simplesmente porque a imagem manterá a proporção da imagem, enquanto max-width e max-height impedirão que fique maior que o contêiner
Uknow