Create a Row of Flexbox Items with a Max Height Defined by One Child

Create a row of flexbox items with a max height defined by one child

Flexbox can't do that natively but it is possible.

You will need an inner element inside the second child which is positioned absolutely.

Here the extra content is/can be hidden with overflow:hidden...or revealed by adding overflow:auto.

.wrapper {  display: flex;  width: 80%;  margin: 1em auto;  border: 2px solid red;}.child {  flex: 1;  border: 2px solid green;}.child:nth-child(2) {  position: relative;  overflow: auto;  /*overflow: hidden; */ /* removed for demo purposes */}.inner {  position: absolute;  top: 0;  left: 0;  width: 100%;  height: 100%;}
<div class="wrapper">  <div class="child">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis tenetur, laboriosam! Ab facilis, officia id delectus eaque expedita quia, incidunt eligendi aut, minus temporibus tenetur.</div>  <div class="child">    <div class="inner">      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae molestiae, libero inventore nobis et veritatis, laborum vitae, vel eaque omnis ad adipisci quia velit blanditiis qui. Cum voluptas quisquam itaque possimus accusamus repellendus quia iure      asperiores. Unde, rerum nihil maiores nisi, iusto voluptate id cumque incidunt, perspiciatis facilis perferendis explicabo.    </div>  </div></div>

How can I make Flexbox children 100% height of their parent?

Use align-items: stretch

Similar to David Storey's answer, my workaround is:

.flex-2 {
display: flex;
align-items: stretch;
}

Note that height: 100% should be removed from the child component (see comments).

Alternatively to align-items, you can use align-self just on the .flex-2-child item you want stretched.

Limit height of flexbox item

Add a wrapper having position: absolute

Now, you can set a min-height to the left most, which the height of the right most will follow.

#wrap { display: flex; }#item-1 { min-height: 100px; background: orange; flex: 1; }#item-2 { position: relative; flex: 1; }#item-wrap {   position: absolute;   left: 0; top: 0;   right: 0; bottom: 0;  overflow: auto; }
<div id='wrap'>  <div id='item-1'>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>    If this gets longer, right most follows<br>  </div>  <div id='item-2'>    <div id='item-wrap'>  I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br> I would like this text to have a scrollbar, and thus not take up more height than the orange box.<br>  </div> </div></div>

How to make all children items the same height in the flexbox, as the one that changes its height?

by making the css property align-items set to stretch
align-items:stretch
, which is the default value of that property and if the flex direction is column just set the width of the child element to 100%, and if the direction is row set height of child to 100%

Element with a child element that has flex-direction: column and max-height; width not expanding when items wrap

Apparently, browsers will not expand flex parents horizontally when using flex-direction:column.

You could try display:grid on the container, this seems to work rather well, although you specify max number of items per row rather than max height:

  display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(7, auto);

See this question for more info.

.nav {
display: flex;
list-style: none;
}

.nav li {
margin: 10px;
background: aqua;
width: 100px;
}

.menu-item {
position: relative;
}

.submenu {
display: none;
position: absolute;
background-color: pink;

}

.submenu ul {
padding-left: 0;
list-style: none;
display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(7, auto);
}

.submenu li {
background-color: yellow;
}

.menu-item:hover .submenu {
display: flex;
}
<ul class="nav">
<li class="menu-item">Nav 1
<div class="submenu">
<ul>
<li>Subnav 1</li>
<li>Subnav 2</li>
<li>Subnav 3</li>
<li>Subnav 4</li>
<li>Subnav 5</li>
<li>Subnav 6</li>
<li>Subnav 7</li>
<li>Subnav 8</li>
<li>Subnav 9</li>
<li>Subnav 10</li>
<li>Subnav 11</li>
<li>Subnav 12</li>
<li>Subnav 13</li>
<li>Subnav 14</li>
<li>Subnav 15</li>
</ul>
</div></li>
<li>Nav 2</li>
</ul>

Make a flexbox row the height of shortest child element?

The goal is to have a row that is the same height as the shortest child element.

This is not something flexbox can do automatically.

You'll need to find a way to tell the container what the height is of the shortest child so it can adjust its height to match. JavaScript seems the way to go.


Take two images as examples, one has 200px height the other has 120px height. This example below works as intended when <img> elements are the direct children of the flex element.

"The example below works as intended..." I presume you mean the height of the row is the height of the shorter image (120px).

In fact, the row is 200px tall:

Sample Image

The shorter image is actually stretching from 120px to 200px because a default setting on a flex container is align-items: stretch, meaning that flex items will expand the full length of the cross-axis. (This is how flexbox can deliver a layout with equal height columns.)

If you override the default with, let's say, align-items: flex-start, you'll see clearly that the taller items sets the height of the container.

Sample Image

.row {  display: flex;  align-items: flex-start;  /* new */  background: orange;}
<div class="row">  <img src="https://s3.amazonaws.com/imagetest.com/purple_200.jpg" />  <img src="https://s3.amazonaws.com/imagetest.com/teal_120.jpg" /></div>

Make children of flex div have same height (on per- row basis)

Typically, to have each column in a flexbox layout have the same height, all you need to do is specify display: flex on the parent element (.parent). In your specific situation, you're setting height: 100% on the child element (.child).

In flexbox, height: 100% actually does the opposite of what you may expect, due to percentage-driven values being based on the height of the containing block. height: auto will allow the element to expand (and is the default).

In short, to have your columns be equal height, simply remove height: 100% from .child:

.parent {  display: flex;  flex-grow: 1;  flex-wrap: wrap;  margin: 0 auto;  max-width: 100%;  width: 100%;}
.child { /*height: 100%;*/ margin-top: 20px; margin: 1%; display: inline-flex;}
.a-title { font-size: 1.3em; font-weight: 700; width: 100%;}
.child .card { border-radius: 3px; border: 1px solid; font-size: .8em; padding: 10px; display: inline-block; overflow: hidden; /* height: 600px; */}
<div class="parent">  <div class="child">    <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p>
<p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div> <div class="child"> <div class="card">
<img src="https://i.imgur.com/D1p6UX3.jpg" width="240" height="240"><br> <p class="a-title"> Title </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> Some example text that I'm too lazy to ipsum right now. </p> <p> <a href="#">Some fake link</a> </p> </div> </div></div>

Flexbox: 4 items per row

You've got flex-wrap: wrap on the container. That's good, because it overrides the default value, which is nowrap (source). This is the reason items don't wrap to form a grid in some cases.

In this case, the main problem is flex-grow: 1 on the flex items.

The flex-grow property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.

More specifically, there are eight flex items in your container. With flex-grow: 1, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.

The solution is to define a width on the items. Try this: