Why second and third flex items doesn't take the remaining height space of container

Why don't 2nd and 3rd items take the remaining height of the container? https://codepen.io/Dimi_0-o/pen/ZEmXPme
Dimi
CodePen
ZEmXPme
...
5 Replies
emmanuelyolou
emmanuelyolouβ€’2y ago
Because you didn't specify any height for them. The default height here is because the container's "align-items" property has a default set to 'stretch'. If updating your HTML is possible, you could put the 2 last items inside a sort of wrapper and then give a flex-direction: column to your container. Your css would then be:
.items-wrapper {
display: flex;
height: 100%;
}

.half-width-item {
flex: 1;
height: 100%;
}

.container {
border: 5px solid black;
height: inherit;
display: flex;
flex-direction: column;
}
.items-wrapper {
display: flex;
height: 100%;
}

.half-width-item {
flex: 1;
height: 100%;
}

.container {
border: 5px solid black;
height: inherit;
display: flex;
flex-direction: column;
}
Chris Bolson
Chris Bolsonβ€’2y ago
An interesting question. One would have thought that, being flex, it would automatically adjust to fill the available height but clearly this not the case. The vertical space has been divided equally according to the number of rows it has calculated that will be needed (I tried adding another row and the height was divided by 3). It then does take into account the height you have defined for the first row but doesn’t re-distribute the remaining height. All of this you know as that is why you asked the question. I wonder if anyone more familiar with the inner workings of flex can explain why this happens. (perhaps the easiest solution would be to use grid)
emmanuelyolou
emmanuelyolouβ€’2y ago
Or a faster solution would be to add css align-content: center to the container. Since the space between the items is created because of how the css flex-wrap: wrap works, it'll solve that. The code would be:
.container {
/*Add your current css for the container here*/
align-content: flex-start;
}

.half-width-item {
flex: 1;
height: calc(100% - 20px);
}
.container {
/*Add your current css for the container here*/
align-content: flex-start;
}

.half-width-item {
flex: 1;
height: calc(100% - 20px);
}
For the .half-width-item, the width is 100% of the height of the container minus 20px. It's because the container flex-direction is set to row by default, so the height of its children won't shrink to fit its height. So to prevent the overflow, we substract the 20px of the full-width-item.
john_galt
john_galtOPβ€’2y ago
@Chris Got the answer, why it is the way it is. 4 hours reading the spec, and finally got it πŸ˜„ The spec says align-content: stretch -- .... the free-space is split equally between all of the lines, increasing their cross size. And the cross size is In a multi-line flex container (even one with only a single line), the cross size of each line is the minimum size necessary to contain the flex items on the line (after alignment due to align-self), and the lines are aligned within the flex container with the align-content property @emmanuelyolou thank you for proposing a solution! Just one wrapper, and direction column is what I needed 🀩 Don't get me wrong I'm grateful to you for your time, but if you allow me, I would correct your proposed solution a bit(after reading the spec for 4 hours got an insight) :
.items-wrapper {
display: flex;
/* height: 100%; */
/*Height is not necessary here, because flex-direction: column will change the main-axis to be from top to bottom in left to right writing mode, and flex factor is working on main axis, so it will stretch it vertically*/
flex: 1;
}

.half-width-item {
flex: 1;
/* height: 100%; */
/*Height is not necessary here also, because the inner flex container will have default direction defined as row and align-items: stretch will be applied in cross-axes which is top to bottom in this case in left to right writing mode*/
}

.container {
border: 5px solid black;
height: inherit;
display: flex;
flex-direction: column;
}
.items-wrapper {
display: flex;
/* height: 100%; */
/*Height is not necessary here, because flex-direction: column will change the main-axis to be from top to bottom in left to right writing mode, and flex factor is working on main axis, so it will stretch it vertically*/
flex: 1;
}

.half-width-item {
flex: 1;
/* height: 100%; */
/*Height is not necessary here also, because the inner flex container will have default direction defined as row and align-items: stretch will be applied in cross-axes which is top to bottom in this case in left to right writing mode*/
}

.container {
border: 5px solid black;
height: inherit;
display: flex;
flex-direction: column;
}
emmanuelyolou
emmanuelyolouβ€’2y ago
Don't worry about that, a correction is always welcome 😁 . And you were right, no need to set an height for .half-width-item as it'll stretch by default. For the wrapper tho, you could stick to flex: 1 or height: 100%, i guess it's a matter of personal preferences. Happy that you found a solution 🀝
Want results from more Discord servers?
Add your server