Image Flex Item Does Not Shrink Height in a Flexbox

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, the item stretches to the height of the image
  • if the image has less height than item, the image stretches to the height of the content 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.

  1. You have the column widths set to flex-grow: 1. This means that flex-basis is still at its default value, auto (content-based). So the column is sized based on the image size. You can add flex-basis: 0, or just use flex: 1.

    Full explanation: Make flex-grow expand items based on their original size




  1. 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 with min-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:

  1. flex-wrap: nowrap ~ flex items are forced to remain on a single line
  2. flex-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 add flex: 0 1 auto to its flex item (inner-flex-container).

  • and because your inner-flex-container is a column flexbox add align-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 new auto value as the initial value of the
min-width and min-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



Leave a reply



Submit