Reputation: 1754
I have four images: two small, two big (dimensions shown in html). They all have their img width set to 100% but their parent div is set to a specific width. When I resize the browser window the smaller images shrink and the larger ones don't, right away.
I have a red border around the divs and green border around the imgs. The smaller images' green borders shrink before the larger ones. Why is that?
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
Upvotes: 15
Views: 32126
Reputation: 55613
This is a rendering difference between chrome and Firefox, but it's easily fixed by this:
.item { flex: 1 1 0; }
This tells the browser that all flex items should start out with 0 width, and all grow at the same rate to fill the remaining space.
Upvotes: 3
Reputation: 11
When I look at your JSFiddle, the issue is simply that the image box sizing doesn't include the border because it needs to be explicitly stated like this :
img { box-sizing: border-box; }
The img tags aren't affected by the flexbox which impacts only their parent div in your JSFiddle (http://jsfiddle.net/brcrnj80/6/) I think every CSS framework on the market includes this by default as a global definition, which makes us forget we need to set it up ourselves when needed.
Upvotes: 1
Reputation: 11839
tl;dr: The items are resizing differently because they have a different flex-basis
, which is based on the image size and is the value that they start flexing (shrinking) from. Every item has to shrink, but the larger items shrink from a larger starting-point, so they're still larger after the shrinking. (There's also a late-in-the-algorithm "clamp" to prevent them from being bigger than their max-width
; this is what keeps the large items from being crazy-huge in this case. But importantly, they start their shrinking from their flex-basis
, and the max-width
clamp is an afterthought.)
FIX: If you give each flex item the same flex-basis, e.g. flex-basis:250px
(the same as their max-width
), you'll probably get the result you're looking for. Updated fiddle: http://jsfiddle.net/brcrnj80/10/
(As noted in another answer, flex: 1 1 0
(which can be expressed more concisely as flex:1
) will also work -- that's setting the flex-basis
to 0, and allowing the flex items to grow (instead of forcing them to shrink) from there, up to their max-width. Produces the same results, just via a different route.)
LONGER EXPLANATION: Here's what happens:
flex-basis:auto
, which in this case means that each flex item starts out its flexing at its image's intrinsic width. So your huge-image flex items have a huge flex basis, and your small-image flex items have a small flex basis.flex-basis
values are larger than the container. They are (because some of your images are huge). So, we have to shrink things.flex-basis
, by whatever portion is necessary to make all of the items fit. So e.g. each item loses 1/4 of its width, for example (if that happens to be the right fraction to make them all exactly fit the container).max-width
. Your flex items with large images will likely violate their max-width
at this state, because e.g. even if we take away 1/4 of their size (in my example), they're still much larger than their max-width:250px
. For any such violations, we freeze the item at its max-width, and we restart the shrinking process. (We do something similar for min-width
violations.)So if there's not enough space for everyone to have 250px of width, your small flex items end up having to do all of the shrinking. (Unless we're constrained enough that the large items would be shrunk to be less than 250px in the first round of shrinking -- e.g. if we're shrinking each item by 90%, say. Though, then the small items will also be shrunk by 90%, and they'll be less than their min-width:60px
, and they'll get frozen at that size and we'll restart the shrinking in the same way that I described above).
See the "Resolving Flexible Lengths" chunk of the spec for more details if you're curious.
Upvotes: 22