Reputation: 932
I want an arbitrary number of images to shrink to fit inside a fixed-width div. It seems that flexbox is good for this purpose, but I can't seem to get it to work with wrapping multiple rows.
If I set flex-flow
to row wrap
and flex
to 1 1 auto
, the images are too big.
.container {
display: flex;
flex-flow: row wrap;
border: 1px solid black;
width: 300px;
height: 300px;
}
.image {
flex: 1 1 auto;
}
img {
max-width: 100%;
}
<div class="container">
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
</div>
If I set flex-flow
to just row
or flex to 1 1 0
, the images don't wrap onto multiple lines:
.container {
display: flex;
flex-flow: row wrap;
border: 1px solid black;
width: 300px;
height: 300px;
}
.image {
flex: 1 1 0;
}
img {
max-width: 100%;
}
<div class="container">
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
</div>
How can I make the images expand enough to wrap as much as possible to fill the div, but not so much they break out of it?
Upvotes: 2
Views: 3550
Reputation: 371143
If I set
flex-flow
torow wrap
andflex
to1 1 auto
, the images are too big.
With flex-basis: auto
your item will take the size of its content (the image, in this case). That's what you're getting in your first demo: The intrinsic width of the image.
If I set
flex-flow
to justrow
or flex to1 1 0
, the images don't wrap onto multiple lines.
With flex-basis: 0
your item will ignore content size and distribute all space in the row evenly among items. That's what's happening in your second demo: It's creating three equal width items. As a result, there is no reason to wrap.
To control the size of flex items you need to define their flex-basis
. Here's a rough sketch:
.container {
display: flex;
flex-flow: row wrap;
align-content: flex-start; /* pack wrapping lines to the top */
border: 1px solid black;
width: 300px;
height: 300px;
}
.image {
flex: 0 0 30%;
margin: 5px;
}
img {
max-width: 100%;
}
<div class="container">
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
<div class="image">
<img src="http://www.placebacon.net/400/300">
</div>
</div>
Upvotes: 2
Reputation: 1303
Just for fun.
var container1 = document.querySelector('.container1'),
container2 = document.querySelector('.container2'),
img = container2.querySelectorAll('.container2 img'),
width = 50,
stop = false;
expand();
function expand() {
for (var i = 0; i < img.length; i++) {
img[i].style.width = width + 'px';
}
if (stop) return;
if (container2.clientHeight < container1.clientHeight) {
width++;
setTimeout(function() {
expand()
}, 10);
} else {
width--;
stop = true;
expand();
}
}
.container1 {
border: 1px solid black;
height: 300px;
width: 300px;
}
.container2 {
font-size: 0;
}
<div class="container1">
<div class="container2">
<img src="http://www.placebacon.net/400/300">
<img src="http://www.placebacon.net/400/300">
<img src="http://www.placebacon.net/400/300">
</div>
</div>
Upvotes: 1