I'm trying to get a two-column flexbox with some content on the left, and the remaining space taken up by an image. The image should be centred in the remaining space and shrink-to-fit. Here's what I've got:
* {
box-sizing: border-box;
}
.small_margin {
margin: 5px;
}
.small_padding {
padding: 5px;
}
.red {
background: #faa;
}
.blue {
background: #aaf;
}
.green {
background: #afa;
}
.small_container {
width: 500px;
display: flex;
flex-direction: row;
}
.large_container {
width: 900px;
display: flex;
flex-direction: row;
}
.image {
max-width: 100%; /* Why does this not work? If you change it to a fixed value (not a percentage) it works. */
max-height: 20em;
}
.image_holder {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
}
<div class="red large_container">
<div class="blue small_margin small_padding" style="width: 120px;">
<h1>This Works</h1>
<p>This is what I want when there is space for the full-size image (restricted to its max-height). It should be centred in the div to the right.</p>
<p>This is good.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
<br>
<div class="red small_container">
<div class="blue small_margin small_padding">
<h1>This Doesn't</h1>
<p>There is now no longer space for the image but instead of reducing its size to 100% of its parent div it just overflows.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
As you can see, the image overflows the flexbox and isn't shrunk-to-fit by the max-width: 100%
. Presumably 100%
doesn't actually mean "100% the width of the parent div
"?
Anyway, is there any way to make this work?
The image has max-width: 100%
. That means that it shouldn't be wider than its parent (the flex item). And this works.
Instead, the problem is that the flex item overflows the flex container. That happens because Flexbox introduces auto
as the initial value of min-width
. When overflow
is visible
, that auto
forces the flex item to grow so that its content doesn't overflow.
Therefore, you can use min-width: 0
.
.image_holder {
min-width: 0;
}
* {
box-sizing: border-box;
}
.small_margin {
margin: 5px;
}
.small_padding {
padding: 5px;
}
.red {
background: #faa;
}
.blue {
background: #aaf;
}
.green {
background: #afa;
}
.small_container {
width: 500px;
display: flex;
flex-direction: row;
}
.large_container {
width: 900px;
display: flex;
flex-direction: row;
}
.image {
max-width: 100%; /* Why does this not work? If you change it to a fixed value (not a percentage) it works. */
max-height: 20em;
}
.image_holder {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
min-width: 0;
}
<div class="red large_container">
<div class="blue small_margin small_padding" style="width: 120px;">
<h1>This Works</h1>
<p>This is what I want when there is space for the full-size image (restricted to its max-height). It should be centred in the div to the right.</p>
<p>This is good.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
<br>
<div class="red small_container">
<div class="blue small_margin small_padding">
<h1>This Doesn't</h1>
<p>There is now no longer space for the image but instead of reducing its size to 100% of its parent div it just overflows.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
Then the image won't overflow the flex container. However, it won't mantain its aspect ratio.
To fix that, you can use object-fit
:
.image {
object-fit: contain;
}
* {
box-sizing: border-box;
}
.small_margin {
margin: 5px;
}
.small_padding {
padding: 5px;
}
.red {
background: #faa;
}
.blue {
background: #aaf;
}
.green {
background: #afa;
}
.small_container {
width: 500px;
display: flex;
flex-direction: row;
}
.large_container {
width: 900px;
display: flex;
flex-direction: row;
}
.image {
max-width: 100%; /* Why does this not work? If you change it to a fixed value (not a percentage) it works. */
max-height: 20em;
object-fit: contain;
}
.image_holder {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
min-width: 0;
}
<div class="red large_container">
<div class="blue small_margin small_padding" style="width: 120px;">
<h1>This Works</h1>
<p>This is what I want when there is space for the full-size image (restricted to its max-height). It should be centred in the div to the right.</p>
<p>This is good.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
<br>
<div class="red small_container">
<div class="blue small_margin small_padding">
<h1>This Doesn't</h1>
<p>There is now no longer space for the image but instead of reducing its size to 100% of its parent div it just overflows.</p>
</div>
<div class="green small_margin image_holder">
<img class="image" src="http://www.gstatic.com/webp/gallery/1.jpg"/>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With