There are lots of questions on SO like this but I haven't found a solution for this specific problem yet. I have a layout with a flex-direction: column
parent that has a fixed width (I am omitting lots of detail about why, not important here), and in it I want a row of <img>
icons, which all have equal image size, to appear side by side and equally sized.
I find that the images lay out horizontally but do not scale down according to flex-shrink: 1
, they appear full size and overflow the parent container with flex-direction: column
.
/* Parent has fixed width and flex-direction: column */
.parent {
display: flex;
flex-direction: column;
width: 300px; /* Something restrictive for this demo */
background-color: lightblue;
}
.icon-wrapper {
display: flex;
flex-wrap: nowrap; /* Maybe unnecessary, but just to force them to stay on one row */
}
.icon-wrapper > img {
flex: 1 1 auto;
}
<p>Problem: The icons overflow the parent, despite being told to shrink if necessary with `flex-shrink: 1`. I have tried `flex-basis: 0` and a few other things.</p>
<div class="parent">
<p>This is the parent, with flex-direction: column. The following icons ought to appear within this parent and not overflow it.</p>
<div class="icon-wrapper">
<!-- I'm using a CDN image that ought to be online for a good while -->
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
</div>
</div>
I normally do fine with the default flex-direction: row
but often get caught out with flex-direction: column
. What am I missing?
With thanks to everyone who commented above, I found comments on Image flex item does not shrink height in a flexbox that suggested using min-width: 0
on the flex items (in my case, the <img>
elements), which seems to work. The images resize, smaller than their natural size if the container is narrower than they fit in, and larger when the container is larger.
See this on codepen, including an example using flexbox gap
: https://codepen.io/neekfenwick/pen/EajjJaq
.parent {
display: flex
flex-direction: column;
width: 30%; /* size according to window */
background-color: lightblue;
justify-content: stretch;
}
.parent.wider {
width: 60%; /* size according to window */
}
.icon-wrapper {
display: flex;
flex-wrap: nowrap;
/* Maybe unnecessary, but just to force them to stay on one row */
}
img {
flex: 1 1 auto;
min-width: 0; /* allows images to resize smaller than their natural size */
}
/* 'with gap' example */
.icon-wrapper.with-gap {
gap: 2rem;
}
/* Make the imgs stand out, for clarity */
.icon-wrapper.with-gap img {
background-color: blue;
border: 1px solid red;
}
<p>See https://stackoverflow.com/a/79641492/141801</p>
<p>With `min-width: 0` on the flex items, the img elements will resize smaller than their natural size when required, and larger too. The container (with the light blue background) is set to a percentage of the window width, so resizing the window should show how they resize. See also codepen at <a href="https://codepen.io/neekfenwick/pen/EajjJaq">https://codepen.io/neekfenwick/pen/EajjJaq</a>.</p>
<div class="parent">
<div class="icon-wrapper">
<!-- I'm using a CDN image that ought to be online for a good while -->
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
</div>
</div>
<p>Here is a wider example</p>
<div class="parent wider">
<div class="icon-wrapper">
<!-- I'm using a CDN image that ought to be online for a good while -->
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
</div>
</div>
<p>Here is an example with `gap`, showing that the flex items are properly respecting the parent flexbox layout.</p>
<div class="parent">
<div class="icon-wrapper with-gap">
<!-- I'm using a CDN image that ought to be online for a good while -->
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
<img src="https://cdn-icons-png.flaticon.com/128/1017/1017466.png">
</div>
</div>
The trick seems to be that an img element will refuse to be shrunk below its natural size due to its default min-size
style value.
This rule also applies to a simple horizontal flexbox containing img elements, see this codepen: https://codepen.io/neekfenwick/pen/dPoorBY - you have to uncomment the min-width rule to allow the images to be shrunk below their natural size. So, this is not some quirk of the flex-direction: column
situation I was in above, but rather a common behaviour of img elements.