Comportamiento de la imagen dentro de flexbox (filas incrustadas en columnas)

El violín abajo tiene tres bloques.

el bloque 1 contiene tres columnas. La columna del medio tiene dos filas dentro, cada una configurada para flexionar: 1.

el bloque 2 contiene tres columnas. La columna del medio tiene dos filas dentro, cada una configurada para flexionar: 1. La segunda fila contiene una imagen de un perro. La imagen no se reducirá a la altura de la fila dentro de la cual está contenida.

el bloque 3 contiene solo la columna central que tiene dos filas dentro, cada una configurada para flexionar: 1. La segunda fila contiene una imagen de un perro. La imagen SE reduce a la altura de la fila dentro de la cual está contenida.

La pregunta es por qué la imagen en la segunda fila de la columna central del bloque 2 no se contrae a la altura de la fila dentro de la cual está contenida? ¿Qué reglas de CSS puedo agregar para que esto suceda?

.block{ height:100px; } .wrapper{ border:5px solid purple; display:flex; flex-direction:row; } .column{ flex:1; border:3px solid yellow; } .middle{ display:flex; flex-direction:column; } .first{ background:red; } .second{ background:orange; } .third{ background:purple; } .row{ flex:1; border:1px solid black; display:flex; align-items:stretch; } img{ flex:1; } 
 

Solución

reemplazar:

 .row { flex: 1; border: 1px solid black; display: flex; align-items: stretch; } 

con:

 .row { flex: 1 1 0px; /* adjustment on this line */ border: 1px solid black; /* no change */ display: flex; /* no change */ align-items: stretch; /* no change */ } 

DEMO 1


Explicación

Tu escribiste:

La pregunta es por qué la imagen en la segunda fila de la columna central del bloque 2 no se contrae a la altura de la fila dentro de la cual está contenida?

Parece que probaste tu código solo en Chrome porque la premisa de tu pregunta es falsa cuando se trata de Firefox e IE11.

En esos buscadores, la imagen del perro en el bloque dos está muy bien dentro del elemento flexible. La imagen está un poco estirada en IE, pero no obstante está contenida.

Tu pregunta parece ser específica de Chrome. (No probé en Safari, pero ese es un navegador WebKit como Chrome, por lo que la solución puede ser similar).

Aquí hay una demostración de tu código original en caso de que quieras probar en todos los navegadores:

DEMO 2

La solución a este problema es interesante porque una diferencia pequeña y aparentemente insignificante en el valor de una propiedad hace una gran diferencia en el procesamiento de Chrome.


Su imagen es un elemento secundario (más específicamente: un elemento flexible) de div.row , un contenedor flexible con dirección de fila.

div.row también es un elemento flexible de un contenedor más grande (en la dirección de la columna) y tiene flex: 1 aplicado. El problema en Chrome está enraizado en esa statement de flex: 1 .

¿Qué significa flex: 1 ?

La propiedad flex es una abreviatura de flex-grow , flex-shrink y flex-basis .

flex: 1 es el equivalente de flex-grow: 1 , flex-shrink: 1 y flex-basis: 0% .

Observe ese signo de porcentaje (%) después del 0 . Se define en los valores comunes de Flex de la flexbox y realmente hace la diferencia.

Prueba esto en Chrome:

Reemplace flex: 1 en div.row con su flex: 1 1 0% equivalente flex: 1 1 0% . Notarás que nada cambia cuando se procesa.

Ahora elimine el signo de porcentaje y ejecútelo nuevamente. La imagen encaja en su lugar.

Haciéndolo flex: 1 1 0px , como se indica en CSS-Tricks , también funciona.

DEMO 3

Entonces, usar px o ninguna unidad, y no un porcentaje, en el 0 corrige el problema en Chrome … y no rompe nada en Firefox.

En IE11, sin embargo, px funciona pero no lo hace. De hecho, sin unidades borra el diseño.

Pero IE11 es otra historia …

En el sitio web de datos de soporte del navegador caniuse.com , IE11 mostraba compatibilidad total con flexbox hasta hace poco, cuando se lo calificó de soporte parcial debido a la “gran cantidad de errores presentes”. Al probar las demostraciones anteriores, IE11 regularmente procesa el mismo código de manera diferente en la actualización. Consulte la pestaña Problemas conocidos en caniuse.com para obtener una lista de problemas.


Tenga en cuenta que FlexBox es compatible con todos los principales navegadores, excepto IE 8 y 9 . Algunas versiones recientes de navegador, como Safari 8 e IE10, requieren prefijos de proveedor . IE11, como se mencionó anteriormente, ofrece soporte parcial debido a varios errores conocidos. Para una forma rápida de agregar todos los prefijos que necesita, use Autoprefixer . Más detalles de compatibilidad del navegador en esta respuesta .

Aquí hay una solución que usa posicionamiento relativo / absoluto. No estoy seguro si es “kosher” como dirían algunos tipos de MXMJ, pero funciona. Ver código agregado en la parte inferior de CSS.

 .block{ height:100px; } .wrapper{ border:5px solid purple; display:flex; flex-direction:row; } .column{ flex:1; border:3px solid yellow; } .middle{ display:flex; flex-direction:column; } .first{ background:red; } .second{ background:orange; } .third{ background:purple; } .row{ flex:1; border:1px solid black; display:flex; align-items:stretch; } img{ flex:1; } /* Added Code */ .middle .row { position: relative; } .middle .row img { position: absolute; top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%); max-width: 95%; max-height: 95%; }