¿Por qué flexbox estira mi imagen en lugar de retener la relación de aspecto?

156

Flexbox tiene este comportamiento donde estira las imágenes a su altura natural. En otras palabras, si tengo un contenedor de flexbox con una imagen secundaria, y cambio el tamaño de esa imagen, la altura no cambia en absoluto y la imagen se estira.

div {
  display: flex; 
  flex-wrap: wrap;
}
img{ 
  width: 50%
}
<div>
    <img src="https://loremflickr.com/400/300" >
    <h4>Appify</h4>
    <p> some text </p>
</div>

¿Qué causa esto?

Añadí Este CodePen para demostrar lo que quiero decir.

sjbuysse
fuente
55
En Firefox e IE funciona bien. En Chrome puedes arreglarlo align-self:flex-start en la imagen. No sé por qué, tal vez el valor predeterminado en Chrome es estirar.
2
También agregando altura: 100%; para que el img solucione el problema, me gustaría saber por qué también estira la imagen.
Paran0a
3
@blonfu, el valor predeterminado en todos los navegadores es align-items: stretch/ align-self: stretch. Si agrega un borde alrededor de cada elemento y lo elimina wrap, notará que todos los elementos se extienden en todos los navegadores: codepen.io/anon/pen/oLXBVx?editors=1100
Michael Benjamin
Ok, aprendo esto, pero las imágenes funcionan de manera diferente en Chrome y el navegador de otros. Chrome no respeta la relación de aspecto si no define la altura.
@blonfu, sí. No hay duda de que hay inconsistencias en el navegador y niveles más granulares.
Michael Benjamin

Respuestas:

365

Se está estirando porque align-selfel valor predeterminado es stretch. Establecer align-selfa center.

align-self: center;

Ver documentación aquí: align-self

pradeep1991singh
fuente
Sí, pero el otro navegador mantiene la relación de aspecto en las imágenes. Chrome ni se aplica flex-base img
9
Creo que align-self: start;puede ser una respuesta más fuerte porque las imágenes deben alinearse verticalmente con la parte SUPERIOR de sus contenedores (no centradas) como lo haría cualquier imagen sin estilo (sin CSS). De cualquier manera, ambas respuestas arreglan el estiramiento. Por lo tanto, depende de lo que OP quiera, por supuesto, simplemente no obtuvo esa impresión de 'centrado verticalmente' de la publicación de OP.
sapo
Si no define un ancho en una imagen y está en un contenedor flexible, se extenderá al 100%. align-self: [flex-start, center...others]evitará que la imagen tome el 100% del ancho de los contenedores flexibles. align-self:centerlo arregla, por supuesto, pero si desea que su imagen comience desde el principio o el final del uso del contenedoralign-items: flex-start or flex-end
cacoder
1
También puede poner align-items: center(o cualquier alineación que se ajuste a sus necesidades) en el padre.
electrovir
16

El atributo clave es align-self: center:

.container {
  display: flex;
  flex-direction: column;
}

img {
  max-width: 100%;
}

img.align-self {
  align-self: center;
}
<div class="container">
    <p>Without align-self:</p>
    <img src="http://i.imgur.com/NFBYJ3hs.jpg" />
    <p>With align-self:</p>
    <img class="align-self" src="http://i.imgur.com/NFBYJ3hs.jpg" />
</div>

dorio
fuente
1

Me enfrenté al mismo problema con un menú de la Fundación. align-self: center;no funciono para mi

Mi solución fue envolver la imagen con un <div style="display: inline-table;">...</div>

isapir
fuente
2
Sin embargo, se trata de flexbox.
Esta es una solución para flexbox. La imagen y div están dentro de un contenedor flexbox.
isapir
0

Agregando marginpara alinear imágenes:

Como queríamos imageque fuera left-aligned, agregamos:

img {
  margin-right: auto;
}

Del mismo modo para imageser right-aligned, podemos agregar margin-right: auto;. El fragmento muestra una demostración para ambos tipos de alineación.

Buena suerte...

div {
  display:flex; 
  flex-direction:column;
  border: 2px black solid;
}

h1 {
  text-align: center;
}
hr {
  border: 1px black solid;
  width: 100%
}
img.one {
  margin-right: auto;
}

img.two {
  margin-left: auto;
}
<div>
  <h1>Flex Box</h1>
  
  <hr />
  
  <img src="https://via.placeholder.com/80x80" class="one" 
  />
  
  
  <img src="https://via.placeholder.com/80x80" class="two" 
  />
  
  <hr />
</div>

Akash
fuente
0

Se estira porque el valor predeterminado de align-self es stretch. hay dos soluciones para este caso: 1. set img align-self: center O 2. set parent align-items: center

img {

   alinearse: centro
}

O

.parent {
  alinear elementos: centro
}
Mohamed Ali
fuente