Redimensionar imagem automaticamente no layout CSS FlexBox e manter a proporção?

98

Usei o layout CSS flex box que aparece conforme mostrado abaixo:

insira a descrição da imagem aqui

Se a tela ficar menor, ela se tornará assim:

insira a descrição da imagem aqui

O problema é que as imagens não são redimensionadas mantendo a proporção da imagem original.

É possível usar CSS puro e layout de flex box para permitir que as imagens sejam redimensionadas se a tela ficar menor?

Aqui está o meu html:

<div class="content">
  <div class="row"> 
    <div class="cell">
      <img src="http://i.imgur.com/OUla6mK.jpg"/>
    </div>
    <div class="cell">
      <img src="http://i.imgur.com/M16WzMd.jpg"/>
    </div>
  </div>
</div>

meu CSS:

.content {
    background-color: yellow;    
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

    background-color: red;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto; 

    padding: 10px;
    margin: 10px;

    background-color: green;
    border: 1px solid red;
    text-align: center;

}
confiar
fonte

Respostas:

83

img {max-width:100%;}é uma maneira de fazer isso. Basta adicioná-lo ao seu código CSS.

http://jsfiddle.net/89dtxt6s/

Ómega
fonte
3
Também é possível fazer isso para a dimensão da altura se a tela ficar menor?
confile de
@confile dependeria muito do layout do código, mas você pode tentar adicionar height:100%;ao imgcss.
Omega de
height: 100vhfaria isso, não height: 100%. O estilo para a altura é sempre complicado.
gdbj
1
Por que isso está marcado como a resposta correta? Omega não o transformou em comportamento padrão do navegador? jsfiddle.net/89dtxt6s/221
VeeK
69

Vim aqui procurando uma resposta para minhas imagens distorcidas. Não tenho certeza absoluta sobre o que o operador está procurando acima, mas descobri que adicionar align-items: centeriria resolver para mim. Lendo os documentos, faz sentido substituir isso se você estiver flexionando imagens diretamente, uma vez que align-items: stretché o padrão. Outra solução é envolver suas imagens com um div primeiro.

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}
gdbj
fonte
11
"Vim aqui à procura de uma resposta às minhas imagens distorcidas" cheguei aqui pelo mesmo motivo e a sua solução ajudou-me (o que estava assinalado como a solução real não me ajudou em nada)
Wagner da Silva
isso me ajudou também, alguém pode explicar porque isso funciona?
Jerry B. estagiário nº 1 de
Esta foi a resposta correta para mim. largura máxima: 100%; não corrigiu a altura (a altura ainda estava ligeiramente esticada). No meu caso, usei align-items: flex-start; porque eu não queria a imagem centralizada verticalmente no contêiner, mas ainda funcionou, pois substitui os itens de alinhamento padrão: stretch; Aqui está uma lista de todos os valores de propriedade para itens de alinhamento que você pode usar para substituir: w3schools.com/cssref/css3_pr_align-items.asp
Kyle Vassella
Tentei muitas coisas, mas seus itens de alinhamento: centrar no pai é o único que deu certo.
Micros de
Esta deve ser a resposta aceita. Alinhar conteúdo não funcionou para mim em termos de alongamento, mas alinhar itens sim, ambos têm funções diferentes. Este SE esclarece a diferença entre os dois: stackoverflow.com/questions/27539262/…
John Ernest
41

Você pode querer experimentar o recurso CSS3 muito novo e simples:

img { 
  object-fit: contain;
}

Ele preserva a proporção da imagem (como quando você usa o truque da imagem de fundo) e, no meu caso, funcionou bem para o mesmo problema.

Porém, tenha cuidado, ele não é compatível com o IE (consulte os detalhes do suporte aqui ).

Lokinou
fonte
4
Lembre-se de que o objeto pai deve ser um flex
Lokinou
Eu tentei isso e funcionou perfeitamente dentro de uma div flex.
Rémy Kaloustian
5

Sugiro procurar background-sizeopções para ajustar o tamanho da imagem.

Em vez de ter a imagem na página, se a definiu como imagem de fundo, você pode definir:

background-size: contain

ou

background-size: cover

Essas opções levam em consideração a altura e a largura ao dimensionar a imagem. Isso funcionará no IE9 e em todos os outros navegadores recentes.

user3196436
fonte
3

Na segunda imagem, parece que você quer que a imagem preencha a caixa, mas o exemplo que você criou FAZ manter a proporção (os animais parecem normais, não são magros ou gordos).

Não tenho ideia se você fez o photoshop dessas imagens como exemplo ou se a segunda é "como deveria ser" também (você disse IS, enquanto no primeiro exemplo você disse "deveria")

De qualquer forma, devo assumir:

Se "as imagens não são redimensionadas mantendo a relação de aspecto" e você me mostra uma imagem que MANTEM a relação de aspecto dos pixels, devo assumir que você está tentando realizar a relação de aspecto da área de "recorte" (o interior de o verde) MANTENDO a proporção dos pixels. Ou seja, você deseja preencher a célula com a imagem, ampliando e cortando a imagem.

Se esse for o seu problema, o código fornecido NÃO reflete "seu problema", mas seu exemplo inicial.

Dadas as duas suposições anteriores, o que você precisa não pode ser realizado com imagens reais se a altura da caixa for dinâmica, mas com imagens de fundo. Usando "background-size: contain" ou estas técnicas (preenchimentos inteligentes em porcentagens que limitam o corte ou os tamanhos máximos em qualquer lugar que você quiser): http://fofwebdesign.co.uk/template/_testing/scale-img/scale- img.htm

A única maneira de isso ser possível com imagens é ESQUECEREMOS sobre sua segunda imagem, e as células têm uma altura fixa, e FORTUNA, a julgar por suas imagens de amostra, a altura permanece a mesma!

Portanto, se a altura de seu contêiner não mudar e você quiser manter suas imagens quadradas, você só precisa definir a altura máxima das imagens para aquele valor conhecido (menos os preenchimentos ou bordas, dependendo da propriedade de tamanho da caixa do células)

Como isso:

<div class="content">
  <div class="row">    
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-2.jpg"/>
      </div>
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-7.jpg"/>
      </div>
    </div>
</div>

E o CSS:

.content {
    background-color: green;
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 10px;
    border: solid 10px red;
    text-align: center;
    height: 300px;
    display: flex;
    align-items: center;
    box-sizing: content-box;
}
img {
    margin: auto;
    width: 100%;
    max-width: 300px;
    max-height:100%
}

http://jsfiddle.net/z25heocL/

Seu código é inválido (tags de abertura são em vez de de fechamento, então elas geram células NESTED, não irmãos, ele usou um SCREENSHOT de suas imagens dentro do código com defeito, e a caixa flexível não está segurando as células, mas os dois exemplos em uma coluna ( você configurou "linha", mas o código corrompido aninhando uma célula dentro da outra resultou em um flex dentro de um flex, finalmente funcionando como COLUNAS. Não tenho ideia do que você queria realizar e como surgiu com esse código, mas estou adivinhando o que você quer é isso.

Eu adicionei display: flex às células também, para que a imagem fique centralizada (acho que display: tablepoderia ter sido usada aqui também com toda essa marcação)

Sergio
fonte
Não parece que você tem a menor idéia de como a pergunta foi respondida por mim. Todos os html e css naquele jsfiddle são fornecidos pelo questionador (@confile). Apenas leia a pergunta e você verá isso. Minha solução é uma linha simples de css img {max-width: 100%;} e o questionador aceitou minha resposta há mais de um ano, pois fornece a solução solicitada. Desejo a você tudo de bom aqui, por favor, tente ler as perguntas corretamente e responder de acordo no futuro, obrigado.
Omega
0

HTML:

<div class="container">
    <div class="box">
        <img src="http://lorempixel.com/1600/1200/" alt="">
    </div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}
Ukr
fonte
0

É assim que eu lidaria com imagens diferentes (tamanhos e proporções) em uma grade flexível.

.images {
  display: flex;
  flex-wrap: wrap;
  margin: -20px;
}

.imagewrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(50% - 20px);
  height: 300px;
  margin: 10px;
}

.image {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */
}
<div class="images">
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1000x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/500x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
</div>

ggzone
fonte
-5

Estou usando jquery ou vw para manter a proporção

jquery

function setSize() {
    var $h = $('.cell').width();
    $('.your-img-class').height($h);
}
$(setSize);
$( window ).resize(setSize); 

vw

 .cell{
    width:30vw;
    height:30vw;
}
.cell img{
    width:100%;
    height:100%;
}
Erick Boileau
fonte