Reputation: 51
I am working with flex layouts and images. My goal is to stack the flex-items on top of each other on smaller screen widths, by setting flex-direction: column;
but there is a strange behavior i can't understand. The flex item that wraps the image seems to take the full width of the image. I have created a CodePen that illustrates the problem. Thank you in advance
Upvotes: 0
Views: 983
Reputation: 484
Let the width of the flex item be dictated by the flex container, then size the image to the size of the flex item.
When you set up a flex-direction: column
flex container, the height of your flex items is controlled by the flex
properties (grow, shrink, basis).
The width of a flex item in a flex-direction: column
flex container can either be dictated by the flex container, or it can be left to the flex item to “decide” how big it wants to be.
In this case align-items: start
controls the width of your flex items. start
means that the items can size themselves however they want, and they will be positioned at the start side of your flex container.
The flex item that wraps your image doesn’t have its own size (it has the default width: auto
), so your image’s width: 100%
can’t be resolved. In that case the image behaves as though it had width: auto
, and basically renders at its full size. Then, the flex item takes on that size, and that’s why it’s so big in your flex container.
You can force all your flex items to be the width of your column flex container by not setting align-items
and letting it use the default normal
value, with stretches the flex items to the width of the flex container. Then your flex items have a specific size, and your image’s width: 100%
can be resolved against that size.
Here’s a working example:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
background-color: #ccc;
padding: 10px;
display: flex;
flex-direction: column;
}
.item {
background-color: #ff1b68;
padding: 40px;
margin: 3px;
color: #fff;
font-size: 40px;
}
.item--2 {
height: 200px;
}
.item--3 {
}
.item--3 img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="item item--1">1</div>
<div class="item item--2">2</div>
<div class="item item--3">
<img
src="https://images7.alphacoders.com/462/thumb-1920-462576.jpg"
alt=""
/>
</div>
</div>
By default, each flex item has align-self: auto
, which means it will look at the flex container’s align-items
value. So you set align-items
once, and all flex items use that. But you can specify different align-self
for each item, if you want to, for example, keep your text flex items align-self: start
, and your image flex item align-self: stretch
.
Upvotes: 2
Reputation: 8600
You can use a calculated width on your image element setting it to view width units => width: calc(100vw - padding - margin)
. So your image element will be 100% of the view width minus the padding and margin of the it and its parent element. Also set your container to min-width: 1000px;
.
If the following is not what you are looking for, please let me know.
Resize the browser to test dynamic resizing of image to fit within viewable screen
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
background-color: #ccc;
padding: 10px;
min-height: 1000px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.item {
background-color: #ff1b68;
padding: 40px;
margin: 3px;
color: #fff;
font-size: 40px;
/*flex-grow: 1;*/
}
.item--2 {
height: 200px;
}
.item--3 {
order: 1;
}
.item--3 img {
width: calc(100vw - 130px);
object-fit: cover;
}
<div class="container">
<div class="item item--1">1</div>
<div class="item item--2">2</div>
<div class="item item--3">
<img src="https://images7.alphacoders.com/462/thumb-1920-462576.jpg" alt="">
</div>
</div>
Upvotes: 1