Image flex item does not shrink height in a flexbox
Note that in your example, the item
is the flex item and not content
- you should check the strech behaviour of item
here.
How can we opt out of img's special behaviour so that it behaves like
other flex items (such as div)?
It behaves like other flex items - <img>
may not be very useful as a flex item but the stretch behaviour works fine:
- if the image has more height than
item
, theitem
stretches to the height of the image - if the image has less height than
item
, the image stretches to the height of thecontent
breaking its aspect ratio.
See demo below:
.container {
border: 1px solid;
display: flex;
}
.item {
background: cadetblue;
}
.content {
width: 200px;
background-color: hotPink;
}
img {
display: block;
}
<h2>Small content</h2>
<div class="container">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content">some text here some text here some text here </div>
</div>
</div>
<br/>
<h2>Large Content</h2>
<div class="container">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>
</div>
</div>
flex items not expanding or shrinking with flex-grow
There are two pieces missing in this puzzle.
You have the column widths set to
flex-grow: 1
. This means thatflex-basis
is still at its default value,auto
(content-based). So the column is sized based on the image size. You can addflex-basis: 0
, or just useflex: 1
.Full explanation: Make flex-grow expand items based on their original size
Flex items, by default, cannot shrink below the size of their content. Their initial setting is
min-width: auto
. You need to override this default withmin-width: 0
.Full explanation: Why don't flex items shrink past content size?
.row {
display: flex;
height: 100vh;
}
.column {
min-width: 0; /* new */
flex: 1; /* adjustment */
border: 2px solid #000;
transition: all 300ms ease-in-out;
}
.column:hover {
flex-grow: 4.3;
}
body {
margin: 0;
}
<div class="row">
<div class="column">
<img src="https://images.pexels.com/photos/2194261/pexels-photo-2194261.jpeg">
</div>
<div class="column">
<img src="https://images.pexels.com/photos/1276553/pexels-photo-1276553.jpeg">
</div>
<div class="column">
<img src="https://images.pexels.com/photos/774731/pexels-photo-774731.jpeg">
</div>
</div>
Flex image won't shrink with screen size when container is a hyperlink
The problem has nothing to do with hyperlinks. You could wrap the image in any element (try a span
or a div
) and it will have the same effect as the a
container.
The problem is the hierarchical structure of a flex container.
When you set an element to display: flex
(or inline-flex
) you establish a flex container.
Only the children of a flex container are flex items. Descendants of a flex container beyond the children are not flex items and don't accept flex properties.
Here are the three flex items:
<a href=""><img src="flash-tooltip.png"></a>
<img src="html-tooltip.png">
<img src="portables-tooltip.png">
The img
in the first element is not a flex item. It is wrapped by the a
element and is therefore a child of a flex item.
The two img
items can shrink because of two default settings on a flex container:
flex-wrap: nowrap
~ flex items are forced to remain on a single lineflex-shrink: 1
~ flex items are permitted to shrink to prevent them from overflowing the container
If you switch to flex-wrap: wrap
and/or flex-shrink: 0
the img
items will no longer shrink.
The a
item does not shrink because of another default setting: min-width: auto
, which means that flex items cannot be smaller than the size of their content. In this case, the a
item cannot shrink below the width of the image.
You can override this setting by adding min-width: 0
to your code.
#container {
display: flex;
}
span {
min-width: 0;
display: flex;
}
img {
min-width: 0;
}
<div id="container">
<span><img src="http://i.imgur.com/60PVLis.png"></span>
<img src="http://i.imgur.com/60PVLis.png">
<img src="http://i.imgur.com/60PVLis.png">
</div>
Nested flexbox does not shrink
You can nest flexboxes a bit more:
make your
outer-flex-child
a flexbox too and addflex: 0 1 auto
to its flex item (inner-flex-container
).and because your
inner-flex-container
is a column flexbox addalign-items: flex-start
to override the default stretch beahvior (align-items: stretch
) that breaks the aspect ratio of the image flex item.
See demo below:
.outer-flex-container {
display: flex;
flex-flow: row nowrap;
border: 1px solid red;
width: 900px;
height: 500px;
}
.outer-flex-container:hover {
width: 500px;
height: 100px;
}
.outer-flex-child {
flex: 0 1 auto;
min-height: 0;
min-width: 0;
display: flex; /* added */
}
.inner-flex-container {
display: flex;
flex-flow: column nowrap;
border: 1px solid grey;
min-height: 0;
min-width: 0;
flex: 0 1 auto; /* added */
align-items: flex-start; /* added */
}
.inner-flex-child {
flex: 0 1 auto;
min-height: 0;
min-width: 0;
max-height: 100%;
max-width: 100%;
opacity: 0.5;
}
<div class="outer-flex-container">
<div class="outer-flex-child">
<div class="inner-flex-container">
<img class="inner-flex-child" src='https://i.stack.imgur.com/QH01k.png' />
</div>
</div>
<div class="outer-flex-child">
<div class="inner-flex-container">
<img class="inner-flex-child" src='https://i.stack.imgur.com/QH01k.png' />
</div>
</div>
</div>
CSS: How to make image not exceed its parents height in flexbox?
The only way to disregard the image height is to use positioning on the image wrapper:
1.position the image absolutely with respect to its wrapper,
2.you can either give a width to the image wrapper or give flex: 1 on item to get half of the available width horizontally.
Source: Image flex item does not shrink height in a flexbox
<html><body>
<div style="display: flex; flex-flow: column; height: 300px;">
<div style="background: green;">HEADER</div>
<div style="background: red;">CAPTION</div>
<div style="background: blue;">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>
<div style="position: relative;background: yellow; flex: 1">
<img style="display:block;width: 100%;height: 100%; object-fit:cover;position: absolute;top: 0;left: 0" src="https://via.placeholder.com/100x500" >
</div>
<div style="background: orange;">
<button>ACTION</button>
</div>
</div>
</body></html>
How to force an image to shrink to fit in flexbox?
You can update your code like below:
img {
/* this will make the image stretch and no overflow*/
height:0;
min-height:100%;
/**/
}
h1 {
background-color: white;
}
.banner {
height: 90vh;
background-color: red;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" >
<div class="banner d-flex flex-column"> <!-- flex container here -->
<h1>
Header
</h1>
<div class="d-flex content flex-grow-1 p-2"> <!-- flex-grow here to fill remaining space -->
<p> Hello World </p>
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png" class="ml-auto">
</div>
</div>
Why image inside flexbox doesn't shrink?
To provide a more reasonable default minimum size for flex items, this
specification introduces a newauto
value as the initial value of the
min-width
andmin-height
properties. - W3C
Chrome has not implemented that yet, but Firefox has it already. What you can do is:
#div1 {
flex: 1 1 100%;
min-width: 0; /* for Firefox and future Chrome etc. */
}
#div2 {
width: 300px;
flex: 0 0 auto; /* do not grow or shrink the size */
}
JSFIDDLE DEMO
Related Topics
What Characters Must Be Escaped in an Http Query String
How to Remove the Top Margin in a Web Page
100% Width Minus Margin and Padding
"Height=100%" Is Not Working in HTML When Using <!Doctype>
How to Align Footer (Div) to the Bottom of the Page
Get Click Event of Each Rectangle Inside Canvas
How to Make a Sticky Footer Using Flexbox in Ie11
Placing a <Div> Within a <Canvas>
Why Does Width Apply to a Button with Display Inline
Table Row Won't Contain Elements with Position:Absolute
How to Include All CSS Kept in a Directory
"Invalid Form Control" Only in Google Chrome
How to Add Background Image for Input Type="Button"
CSS Filter:Invert Not Working with Background-Color