Justin Wyllie Justin Wyllie - 6 months ago 11
HTML Question

Images in flex items causing equal width to break

enter image description here

The red borders are around flex items. They have

flex-grow: 1


These items are contained in a flex container:

width: 100%
display: flex
flex-direction: row
align-items: flex-end


As you can see the vertical alignment is working fine.

When I put the images in, the width of the images pushes the flex items to be bigger or smaller than they should be. The width of the images overrides the width of the flex items. What I want to say is something like:

Firstly make the flex items all the same size and then size the contained images (whatever their natural size) to be the size of their container (the flex item). I've tried
width: 100%
and
width: auto
on the images. Didn't help.

This image shows the equally spaced flex items (red borders). I want the images to fit into these boxes without causing the width of the box to change. This is the behaviour I get if I replace the flex items with table cells.

Screenshot

This Fiddle shows the 3 equal boxes: https://jsfiddle.net/justinwyllie/zdrd89gu/



.flex-container {
display: flex;
flex-direction: row;
align-items: flex-end;
}

.flex-boxes {
flex-grow: 1;
border: 2px solid red;
}

<div class="flex-container">
<div class="flex-boxes">A</div>
<div class="flex-boxes">B</div>
<div class="flex-boxes">C</div>
</div>





This one shows an image in the middle flex item. It has completely messed up the equal boxes. The question is what do I need to do to make the cat fit into the middle box? (Fit width-wise that is; i don't mind about height).

https://jsfiddle.net/justinwyllie/zdrd89gu/1/



.flex-container {
display: flex;
flex-direction: row;
align-items: flex-end;
}

.flex-boxes {
flex-grow: 1;
border: 2px solid red;
}

.cat {
width: auto;
}

<div class="flex-container">
<div class="flex-boxes">A</div>
<div class="flex-boxes">
<img class="cat" src="http://www.publicdomainpictures.net/pictures/30000/velka/annoyed-cat.jpg" />
</div>
<div class="flex-boxes">C</div>
</div>




Answer

The flex-grow property tells a flex item how to consume available space in the container.

In your second image, the empty items are all equal width because flex-grow: 1 tells them to distribute available space in the container equally among themselves.

Any content you put in these items can potentially override flex-grow since, as mentioned, flex-grow is based on the free space in the container and content consumes space.

If you want the items to maintain a fixed width, use flex-basis.

So instead of:

flex-grow: 1;

Try:

flex: 0 0 20%; /* don't grow, don't shrink, fixed width at 20% */

The 20% is just an example, if you wanted five items per row.

Here's your revised code:

jsFiddle

.flex-container {
  display: flex;
  flex-direction: row;
  align-items: flex-end;
}
.flex-boxes {
  /* flex-grow: 1;       <-- REMOVE */
  flex: 0 0 33.33%;      /*  NEW    */
  border: 2px solid red;
}
.cat {
  width: auto;
}
<div class="flex-container">
  <div class="flex-boxes">A</div>
  <div class="flex-boxes">
    <img class="cat" src="http://www.publicdomainpictures.net/pictures/30000/velka/annoyed-cat.jpg" />
  </div>
  <div class="flex-boxes">C</div>
</div>

Learn more here:

Comments