Why do flexbox images change differently depending on their original size?

I have four images: two small, two large (sizes shown in html). Everyone has their img width set to 100%, but their parent div is set to a specific width. When I resize my browser window, smaller images are compressed, and large ones are not.

I have a red border around divs and a green border around imgs. The green borders of smaller images are reduced to larger ones. Why is this?

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

thanks

+7
css image flexbox
source share
2 answers

tl; dr: elements change differently because they have different flex-basis , which are based on the size of the image and are the value from which they begin to bend (contract). Each item must contract, but large objects contract from a larger starting point, so after compression they become even larger. (There is also a “clip” at the end-in-algorithm so that they do not become larger than their max-width , this is what keeps large objects from craziness - huge in this case. But it’s important that they begin to shrink from their flex-basis , and max-width clamping is an afterthought.)

FIX:. If you give each element of flexibility the same flexible foundation, for example. flex-basis:250px (same as their max-width ), you are likely to get the result you are looking for. Updated fiddle: http://jsfiddle.net/brcrnj80/10/

(As indicated in another answer, flex: 1 1 0 (which can be expressed more concisely as flex:1 ) will also work - that setting flex-basis to 0 and allowing flexible elements to grow (instead of forcing them to compress them) from there to the maximum width. Produces the same results only through a different route.)

ADDITIONAL EXPLANATION:. What's happening:

  • By default, everything has flex-basis:auto , which in this case means that each flexibility element begins to bend along its internal image width. Thus, your flexible elements with a huge image have great flexibility, and your flexible elements of a small image have little flexibility.
  • We can see if the sum of the flex-basis element values ​​is greater than the container. They are (because some of your images are huge). So we have to cut everything.
  • We compress each flexible element “fairly”, starting with its flex-basis , with any part necessary to ensure that all elements are consistent. So, for example, each element, for example, loses 1/4 of its width (if it is the right lobe, so that they all correspond exactly to the container).
  • NOW, we are checking to see if any of these “preliminary” element sizes violate the max-width element. Your flexible elements with large images are likely to violate their max-width in this state, because, for example, even if we remove 1/4 of their size (in my example), they are still much larger than their max-width:250px . For any such violations, we freeze the element with the maximum width, and we restart the compression process. (We do something similar for min-width violations.)
  • When you restart the compression process, large images are frozen with a width of 250 pixels, and smaller images are responsible for all reductions.

So, if there is not enough room for each for 250px width, your little flexible elements will eventually have to do all the shrinking. (If we are not limited enough that large items will be reduced to less than 250 pixels in the first round of reduction - for example, if we reduce each item by 90%, say. Although, then small items will also be reduced by 90%, and they will be smaller, than their min-width:60px , and they will be frozen in this size, and we will restart the reduction as described above).

For more details, see the section "Allowing Flexible Length" of the specification , if you are interested.

+10
source share

Someone posted the answer here earlier (I'm pretty sure, I'm not sure why it was deleted?).

Yes, this is a rendering difference between chrome and firefox, but this is easily fixed by this:

 .item { flex: 1 1 0; } 

This tells the browser that all flex elements should start at 0 width, and they all grow at the same speed to fill the remaining space.

+2
source share

All Articles