Why Do Flexbox Item Images Resize Differently According to Their Initial Size

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

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.

Why does flexbox stretch my image rather than retaining aspect ratio?

It is stretching because align-self default value is stretch.
Set align-self to center.

align-self: center;

See documentation here:
align-self

display:flex & image sizing/centering

It seems flexbox do not scale down images (that have an intrinsic aspect ratio) correctly in browsers at the moment, at least!
(For more info, you can look at this discussion)

So I have two solutions for this:

  1. Set flex-basis for the img

.image_block {

padding: 20px;

height: 140px;

background: #eee;

display: flex;

}

.image_block img {

margin: auto;

max-width: 170px;

max-height: 90px;

flex-basis: 170px;

}
<div class="image_block">

<img src="http://www.paulruocco.com/jobjacket/assets/uploads/company_uploads/image_070816132332577fe19495484.png" />

</div>

Maintain image aspect ratio when changing height

For img tags if you define one side then other side is resized to keep aspect ratio and by default images expand to their original size.

Using this fact if you wrap each img tag into div tag and set its width to 100% of parent div then height will be according to aspect ratio as you wanted.

http://jsfiddle.net/0o5tpbxg/

* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}

Why are my images overflowing the window with flexbox?

Actually it was the paragraph in the #places div that was causing the images to shrink much more than required. Figured out that had to place it out of the #places div and inside the .showcase div like :

<div class="showcase shadow">
<p class="category">Places</p> // like this
<div id="places">
<div>
<img src="img\Taj Hotel.png" alt="Sample Image">
</div>
<div>
<img src="img\Gateway of India.png" alt="Sample Image">
</div>
<div>
<img src="img\Shack at Goa.png" alt="Sample Image">
</div>
</div>

<p class="more-text">View more...</p>
</div>

and than setting the width of the images to 100% like gagan mentioned :

.showcase {
width: 100%;
margin-top: 5%;
display: inline-block;

#places {
width: 100%;
display: flex;
justify-content: flex-end;

div:nth-of-type(1) {
align-self: flex-end;
}

div {
margin-left: 0.5%;

img {
width: 100%; //width to 100%
}
}

}
}

Flex items do not vertically shrink when child images vertically shrink in IE

Maybe you missed this article in Microsoft documentation:

  • http://connect.microsoft.com/IE/feedbackdetail/view/891815/ie11-flexbox-items-do-not-vertically-shrink-when-child-images-vertically-shrink

From the article:

If anyone arrives here trying to fix this maddening issue in IE11 - I suggest adding a min-height: 1px to the flex wrapper of your image to force IE to recalculate the size based on an image that has height: auto applied to it. This solved the issue and had no impact on other browsers, so I didn't need to target IE11 specifically.

So, add min-height: 1px to .body:

revised fiddle

.wrapper {

display: flex;

flex-direction: column;

border: 1px solid black;

width: 400px;

}

.head {

background-color: rgba(200, 100, 100, 1);

}

.body {

min-height: 1px; /* NEW (for IE11) */

background-color: rgba(200, 200, 200, 1);

}

.inner {

display: flex;

flex-direction: row;

}

.inner-content {

flex: 1 1 75%;

}

.inner-image {

flex: 1 1 25%;

}

.inner-image img {

border-radius: 50%;

max-width: 100%;

flex-shrink: 0;

}

.foot {

background-color: rgba(100, 200, 100, 1);

}
<div class="wrapper">

<div class="head">

<p>Header content</p>

</div>

<div class="body">

<div class="inner">

<div class="inner-content">

<p>The image to the right is normally 253px high/wide</p>

</div>

<div class="inner-image">

<img src="http://connectorsdemo.azurewebsites.net/images/MSC12_Oscar_002.jpg">

</div>

</div>

</div>

<div class="foot">

<p>Footer Content</p>

</div>

</div>


Related Topics



Leave a reply



Submit