Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
639 views
in Technique[技术] by (71.8m points)

css - Why do flexbox item images resize differently according to their initial size?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

  1. By default, everything has 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.
  2. We see if the sum of the flex items' flex-basis values are larger than the container. They are (because some of your images are huge). So, we have to shrink things.
  3. We shrink each flex item "fairly", starting from its 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).
  4. NOW, we check if any of these "tentative" item sizes violate the item's 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.)
  5. In the restarted shrinking process, the large images are frozen at 250px-width, and the smaller images are responsible for all of the shrinking.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...