guia grow basis css image flexbox

css - grow - ¿Por qué las imágenes de elementos de la caja flexible cambian de tamaño de forma diferente según su tamaño inicial?



flexbox guia (2)

Tengo cuatro imágenes: dos pequeñas, dos grandes (las dimensiones se muestran en html). Todos ellos tienen su ancho de img establecido en 100%, pero su div principal se establece en un ancho específico. Cuando cambio el tamaño de la ventana del navegador, las imágenes más pequeñas se contraen y las más grandes no, de inmediato.

Tengo un borde rojo alrededor de los divs y un borde verde alrededor de los imgs. Los bordes verdes de las imágenes más pequeñas se encogen antes que los más grandes. ¿Porqué es eso?

http://jsfiddle.net/brcrnj80/6/

img { border: 3px solid green; width: 100%; } .item { border: 1px solid red; max-width: 250px; min-width: 60px; margin: 10px; }

Gracias


Alguien publicó la respuesta aquí antes (estoy casi seguro, no estoy seguro de por qué se eliminó).

Sí, esta es una diferencia de renderizado entre Chrome y Firefox, pero se soluciona fácilmente con esto:

.item { flex: 1 1 0; }

Esto le dice al navegador que todos los artículos flexibles deben comenzar con 0 de ancho, y todos crecerán a la misma velocidad para llenar el espacio restante.


tl; dr: los elementos cambian de tamaño de forma diferente porque tienen una flex-basis diferente, que se basa en el tamaño de la imagen y es el valor desde el que empiezan a flexionarse (contracción). Cada artículo tiene que reducirse, pero los artículos más grandes se contraen desde un punto de partida más grande, por lo que siguen siendo más grandes después de la contracción. (También hay una "abrazadera" tardía en el algoritmo para evitar que sean más grandes que su max-width ; esto es lo que evita que los artículos grandes se vuelvan locos, enorme en este caso. Pero, lo que es más importante, comienzan a reducirse de su flex-basis , y la abrazadera de max-width es una idea de último momento).

REVISIÓN: si le das a cada artículo flexible la misma base flexible, por ejemplo, flex-basis:250px (el mismo que su max-width ), es probable que obtengas el resultado que estás buscando. Fiddle actualizado: http://jsfiddle.net/brcrnj80/10/

(Como se señala en otra respuesta, flex: 1 1 0 (que se puede expresar de forma más concisa como flex:1 ) también funcionará, es decir, establecer la flex-basis en 0 y permitir que los elementos flexibles crezcan (en lugar de forzarlos) encoger ) desde allí, hasta su ancho máximo. Produce los mismos resultados, solo a través de una ruta diferente).

MAYOR EXPLICACIÓN: Esto es lo que sucede:

  1. Por defecto, todo tiene flex-basis:auto , que en este caso significa que cada elemento flexible comienza su flexión en el ancho intrínseco de su imagen. Por lo tanto, sus elementos flexibles de gran tamaño tienen una gran base flexible, y los elementos flexibles de imagen pequeña tienen una pequeña base flexible.
  2. Vemos si la suma de los valores de flex-basis de los ítems flex-basis es mayor que el contenedor. Lo son (porque algunas de tus imágenes son enormes). Entonces, tenemos que reducir las cosas.
  3. Contraemos cada elemento de flexión "bastante", comenzando desde su flex-basis , por cualquier porción que sea necesaria para que quepan todos los artículos. Entonces, por ejemplo, cada artículo pierde 1/4 de su ancho, por ejemplo (si esa es la fracción correcta para hacer que todos encajen exactamente en el contenedor).
  4. AHORA, verificamos si alguno de estos tamaños de elementos "tentativos" viola el max-width del artículo. Es probable que sus elementos flexibles con imágenes grandes violen su max-width en este estado, porque, por ejemplo, incluso si quitamos 1/4 de su tamaño (en mi ejemplo), todavía son mucho más grandes que su max-width:250px . Para tales violaciones, congelamos el artículo en su ancho máximo y reiniciamos el proceso de reducción. (Hacemos algo similar para violaciones de min-width ).
  5. En el proceso de contracción reiniciado, las imágenes grandes se congelan a 250 píxeles de ancho, y las imágenes más pequeñas son responsables de la reducción.

Entonces, si no hay suficiente espacio para que todos tengan 250px de ancho, sus pequeños artículos flexibles terminarán teniendo que hacer todo el encogimiento. (A menos que estemos lo suficientemente constreñidos como para que los artículos grandes se reduzcan a menos de 250px en la primera ronda de contracción , por ejemplo, si estamos reduciendo cada elemento en un 90%, por ejemplo. se redujo en un 90%, y será menor que su min-width:60px , y se congelarán en ese tamaño y reiniciaremos la contracción de la misma manera que describí anteriormente).

Consulte el fragmento "Resolviendo longitudes flexibles" de la especificación para obtener más detalles si tiene curiosidad.