Flex-shrink not working as expected

Multi tool use


Flex-shrink not working as expected
I'm starting to work with flexbox, and, in order to understand flex-grow
and flex-shrink
, I used a simple program that displays two blocks and makes them take up the whole width using flex-grow: 2
in one of them and flex-grow: 1
in the other.
flex-grow
flex-shrink
flex-grow: 2
flex-grow: 1
If I check the following line in the console: $(".one").width() === $(window).width() /3
it returns true. So far, so good.
$(".one").width() === $(window).width() /3
The problem appears when I reduce the window size, because as soon as I do this the same line in the console ($(".one").width() === $(window).width() /3
) starts returning false.
$(".one").width() === $(window).width() /3
I know the default value for flex-shrink
is 1
. Wouldn't that mean that the proportions between both blocks would be maintained (since they are both being shrunk by the same amount)? Can anyone explain why this result happens?
flex-shrink
1
Here's my code:
* {
font-family: verdana;
margin: 0;
}
body {
background: #eee;
}
.wrapper {
width: 100%;
max-width: 2000px;
margin: 0 auto;
}
.flex-container {
display: flex;
background-color: white;
}
.box {
height: 100px;
}
.one {
background-color: red;
flex-grow: 1;
}
.two {
background-color: blue;
flex-grow: 2;
}
<div class="wrapper">
<div class="flex-container">
<div class="box one"></div>
<div class="box two"></div>
</div>
</div>
@Michael It seems to me that the more I shrink it, the less the difference between the width of the two blocks
– Larpee
Mar 15 '17 at 21:27
if you
parseInt()
the values, it's always true.– Michael Coker
Mar 15 '17 at 21:35
parseInt()
4 Answers
4
flex-shrink
is designed to distribute negative free space in the container.
flex-shrink
In other words, it only works when flex items are big enough to overflow the container.
You're not having that problem here. There is no negative space. Therefore, I don't believe flex-shrink
is having any effect on your layout.
flex-shrink
flex-grow
is consuming the positive free space and seems to be working fine.
flex-grow
You would need to set a flex-basis
or add content to the items to put flex-shrink
in play.
flex-basis
flex-shrink
https://www.w3.org/TR/css-flexbox-1/#flex-property
Then how does the browser resize the elements when I manually resize the window?
– Larpee
Mar 15 '17 at 21:56
That's got nothing to do with
flex-shrink
. You're reducing / expanding the width of the container, which is decreasing / increasing the space in the container, and flex-grow
is adjusting accordingly.– Michael_B
Mar 15 '17 at 22:00
flex-shrink
flex-grow
Then what does
flex-shrink
do? (I'm sorry if I'm being annoying but I'm really new at this and I'm trying to understand as much as I can)– Larpee
Mar 15 '17 at 22:42
flex-shrink
Here's an explanation for
flex-shrink
: stackoverflow.com/q/34753491/3597276– Michael_B
Apr 10 '17 at 0:05
flex-shrink
Thank you @Michael_B
– Larpee
Apr 10 '17 at 19:22
This is related to float calculations. Your flex code is working perfectly fine, the problem arises from the arithmetic operation, where the width of the container might not perfectly divide to 3, so the result will be a floating number which might or not be rounded to the closest number, so that's why width of your first flexbox item might not be equal to width / 3 because of that rounding.
Tested with Chrome Inspector.
While not relevant to your question it might be worth noting:
flex-wrap
takes precedence over flex-shrink
, unless the item is wider than the container.
flex-wrap
flex-shrink
See also Is there any use for flex-shrink when flex-wrap is wrap?
Take a look at https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-13
They suggest using the shorthand flex: [number];
because it intelligently sets the default flex-shrink
to 0
. Just because the default for flex-shrink
is 1
doesn't mean that 1
is what you want. I haven't been using flexbox that long, but I've yet to come across a scenario in which I've had to specify a flex-shrink
. 0
has been working for me thus far. Maybe somebody else can provide a scenario for using it.
flex: [number];
flex-shrink
0
flex-shrink
1
1
flex-shrink
0
TLDR
Use flex
attribute instead of flex-grow
flex
flex-grow
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Seems like it's working to me. The widths are off by a fraction of a pixel on resize at most. codepen.io/anon/pen/wJrpWN
– Michael Coker
Mar 15 '17 at 21:26