I’m very confused on why my flex-shrink isn’t working until I set a fixed width or height on the item I want shrunk faster than the others.
https://codepen.io/MH-123/pen/ExJWQWq
You can see here how the left and right column shrink at the same rate, and the flex-shrink doesn’t seem to affect it. But if you change colLeft and colRight’s width to 300px for example, once the container shrinks to 600px and less, THEN the flex-shrink starts kicking in.
I want to know how I can make the flex-shrink activate right away without setting the fixed width of the left column.
If the only way to achieve this is to set an arbitrary width to flex items, what’s the best practice? Using px? em?
*,
*::before,
*::after {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
}
body {
margin: 0;
height: 100vh;
width: 100vw;
border: 2px solid black;
}
.container {
width: 100%;
height: 100%;
border: 2px solid blue;
display: flex;
justify-content: center;
align-items: center;
flex: row nowrap;
}
.colLeft, .colRight {
height: 100%;
width: 50%;
border: 2px solid red;
display: flex;
flex-flow: column nowrap;
justify-content: space-evenly;
align-items: center;
align-content: space-around;
}
.colLeft {
flex: 1 10 auto;
}
.colRight {
flex: 1 1 auto;
}
<body>
<div class="container">
<div class="colLeft">
1
</div>
<div class="colRight">
2
</div>
</div>
</body>
3
Answers
You should only need
flex: 10;
respectiveflex: 1;
.E. g. you use
flex-basis
, notflex-shrink
.There is nice explanation of how flexbox works.
You only have to change the width to 100% from 50% in
Flexbox works by distributing space. If there is more space than content, it distributes the extra space to it’s children based on their ratios of flex-grow. If there is space missing and children do not fit, they are shrunk, if possible, according to their ratios of flex-shrink.
The basis for calculating if there is enough space if flex-basis and if none is defined, it uses
auto
which is roughly speaking the natural size of the element.If you do not specify any width or flex-basis for the children, it’s based on the content the children have, in your example, the "1" and "2" respectively. You’re specifying the flex-grow to be 1 and there is a lot of extra space, the content of the flex items is small, so what it does is that it takes all that extra space and distributes it 1:1 to the two elements. This is why if the content was "111111" and "2", they wouldn’t be equal size. Only the empty space gets distributed, so one would be "size of 111111 + 50% of empty space", the other would be "size of 2 + 50% of empty space" which is not the same, 111111 is wider.
As there is enough space, flex-shrink is never even considered.
If you put in a long long text like Lorem Ipsum, then the size of these elements would be larger than the size of the container and instead of distributing extra space 1:1, it has to shrunk them in 1:10.
As soon as you specify the width of the elements to be 50%, you’re saying that both elements fit perfectly and there is no growing or shrinking at all, 50% + 50% = 100% all good.
If you specify the width of the items to be 100%, then they are 200% of container together, so shrinking kicks in and flexbox shrinks it in 1:10 ratio again.
This is what you found out yourself, so hope this explanation helps. It’s always either growing (extra space available) or shrinking (not enough space) based on basis (or content itself if no basis/width is used).
However, even the shrinking considers the basis! If you have a loooong text in left column and short in right column, the columns will not be 1:10 wide, they will be shrunk at 1:10 ratio after taking in the basis:
There is a lot going on and we have not even added margins and justify-content, that’s where the fun begins!