¿Cambiar el tamaño de la imagen automáticamente en CSS FlexBox Layout y mantener la relación de aspecto?

98

He usado el diseño de caja flexible CSS que aparece como se muestra a continuación:

ingrese la descripción de la imagen aquí

Si la pantalla se vuelve más pequeña, se convierte en esto:

ingrese la descripción de la imagen aquí

El problema es que las imágenes no se redimensionan manteniendo la relación de aspecto de la imagen original.

¿Es posible usar CSS puro y el diseño de caja flexible para permitir que las imágenes cambien de tamaño si la pantalla se vuelve más pequeña?

Aquí está mi 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>

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

}
confile
fuente

Respuestas:

83

img {max-width:100%;}es una forma de hacer esto. Solo agréguelo a su código CSS.

http://jsfiddle.net/89dtxt6s/

Omega
fuente
3
¿También es posible hacer esto para la dimensión de altura si la pantalla se vuelve más pequeña?
confile el
@confile dependería mucho del diseño de su código, pero puede intentar agregarlo height:100%;a imgcss.
Omega
height: 100vhlo haría, no height: 100%. El estilo para la altura siempre es complicado.
gdbj
1
¿Por qué está marcado como la respuesta correcta? ¿No lo convirtió Omega en el comportamiento predeterminado del navegador? jsfiddle.net/89dtxt6s/221
VeeK
69

Vine aquí buscando una respuesta a mis imágenes distorsionadas. No estoy totalmente seguro de lo que está buscando la operación anterior, pero descubrí que agregarlo align-items: centerlo resolvería por mí. Al leer los documentos, tiene sentido anular esto si está flexionando imágenes directamente, ya que align-items: stretches el valor predeterminado. Otra solución es envolver sus imágenes con un div primero.

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}
gdbj
fuente
11
"Vine aquí buscando una respuesta a mis imágenes distorsionadas" llegué aquí por la misma razón y su solución me ayudó (lo que se marcó como la solución real no me ayudó en absoluto)
Wagner da Silva
esto también me ayudó, ¿alguien puede explicar por qué funciona?
Jerry B. becario n. ° 1
Esta fue la respuesta correcta para mí. ancho máximo: 100%; no corrigió la altura (la altura todavía estaba ligeramente estirada). En mi caso utilicé align-items: flex-start; porque no quería que la imagen se centrara verticalmente en el contenedor, pero aún así funcionó, ya que anula los elementos de alineación predeterminados: estiramiento; Aquí hay una lista de todos los valores de propiedad para los elementos de alineación que podría usar para anular: w3schools.com/cssref/css3_pr_align-items.asp
Kyle Vassella
Intenté muchas cosas, pero su align-items: center on the parent es el único que hizo el truco.
Micros
Esta debería ser la respuesta aceptada. Align-content no funcionó para mí en términos de estiramiento, pero align-items sí, ambos tienen funciones diferentes. Este SE aclara la diferencia entre los dos: stackoverflow.com/questions/27539262/…
John Ernest
41

Es posible que desee probar la característica CSS3 muy nueva y simple:

img { 
  object-fit: contain;
}

Conserva la relación de la imagen (como cuando usas el truco de la imagen de fondo) y, en mi caso, funcionó muy bien para el mismo problema.

Sin embargo, tenga cuidado, no es compatible con IE (consulte los detalles de soporte aquí ).

Lokinou
fuente
4
Recuerde que el objeto padre tiene que ser un flex
Lokinou
Probé esto y funcionó perfectamente dentro de un div flex.
Rémy Kaloustian
5

Sugiero buscar background-sizeopciones para ajustar el tamaño de la imagen.

En lugar de tener la imagen en la página, si la tiene configurada como imagen de fondo, puede configurar:

background-size: contain

o

background-size: cover

Estas opciones tienen en cuenta tanto el alto como el ancho al escalar la imagen. Esto funcionará en IE9 y en todos los demás navegadores recientes.

user3196436
fuente
3

En la segunda imagen, parece que desea que la imagen llene el cuadro, pero el ejemplo que creó SÍ mantiene la relación de aspecto (las mascotas se ven normales, no delgadas ni gordas).

No tengo ni idea de si hiciste photoshop de esas imágenes como ejemplo o si la segunda es "cómo debería ser" también (dijiste SI, mientras que en el primer ejemplo dijiste "debería")

De todos modos, tengo que asumir:

Si "las imágenes no se redimensionan manteniendo la relación de aspecto" y me muestra una imagen que SÍ mantiene la relación de aspecto de los píxeles, debo asumir que está tratando de lograr la relación de aspecto del área de "recorte" (el interior de el verde) MIENTRAS mantiene la relación de aspecto de los píxeles. Es decir, desea llenar la celda con la imagen, agrandando y recortando la imagen.

Si ese es su problema, el código que proporcionó NO refleja "su problema", sino su ejemplo inicial.

Dadas las dos suposiciones anteriores, lo que necesita no se puede lograr con imágenes reales si la altura de la caja es dinámica, pero con imágenes de fondo. Ya sea utilizando "background-size: contener" o estas técnicas (rellenos inteligentes en porcentajes que limitan el recorte o los tamaños máximos en cualquier lugar que desee): http://fofwebdesign.co.uk/template/_testing/scale-img/scale- img.htm

La única forma en que esto es posible con las imágenes es si nos OLVIDAMOS de su segunda imagen, y las celdas tienen una altura fija, y AFORTUNADA, a juzgar por sus imágenes de muestra, ¡la altura permanece igual!

Entonces, si la altura de su contenedor no cambia y desea mantener sus imágenes cuadradas, solo tiene que establecer la altura máxima de las imágenes en ese valor conocido (menos rellenos o bordes, según la propiedad de tamaño de caja del células)

Me gusta esto:

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

Y el 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/

Su código no es válido (las etiquetas de apertura son en lugar de las de cierre, por lo que generan celdas NESTED, no hermanos, usó una CAPTURA DE PANTALLA de sus imágenes dentro del código defectuoso, y el cuadro flexible no contiene las celdas sino ambos ejemplos en una columna ( configuraste "fila", pero el código corrupto que anidaba una celda dentro de la otra resultó en una flexión dentro de una flexión, que finalmente funcionó como COLUMNAS. No tengo idea de lo que querías lograr y cómo se te ocurrió ese código, pero ' Supongo que lo que quieres es esto.

También agregué display: flex a las celdas, por lo que la imagen se centra (creo que display: tablepodría haberse usado aquí también con todo este marcado)

sergio
fuente
No parece que tenga la menor idea de cómo respondí la pregunta. Todo html y css en ese jsfiddle es lo que ha proporcionado el interrogador (@confile). Simplemente lea la pregunta y lo verá. Mi solución es una línea simple de css img {max-width: 100%;} y el interrogador aceptó mi respuesta hace más de un año, ya que proporciona la solución solicitada. Le deseo todo lo mejor aquí, intente leer las preguntas correctamente y luego responda en consecuencia en el futuro, gracias.
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;
}
Reino Unido
fuente
0

Así es como manejaría diferentes imágenes (tamaños y proporciones) en una cuadrícula flexible.

.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
fuente
-5

Estoy usando jquery o vw para mantener la proporción

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
fuente