12

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.

If I check the following line in the console: $(".one").width() === $(window).width() /3 it returns true. So far, so good.

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.

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?

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 Benjamin
  • 346,931
  • 104
  • 581
  • 701
Larpee
  • 800
  • 1
  • 7
  • 18

4 Answers4

13

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.

  • So if you have flex-wrap enabled and you're expecting two items to shrink to fit side by side on a single row they won't, they'll wrap first even if there's plenty of shrink-potential.
  • If the item is wider than the parent container it can't wrap so it will shrink if it can.
  • You'd have to solve this with min/max widths, make the initial size smaller (this is probably the best way) or creating a new parent container without flex-wrap.

See also Is there any use for flex-shrink when flex-wrap is wrap?

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
11

flex-shrink is designed to distribute negative free space in the container.

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-grow is consuming the positive free space and seems to be working fine.

You would need to set a flex-basis or add content to the items to put flex-shrink in play.

https://www.w3.org/TR/css-flexbox-1/#flex-property

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 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 Benjamin Mar 15 '17 at 22:00
  • 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
  • Here's an explanation for `flex-shrink`: http://stackoverflow.com/q/34753491/3597276 – Michael Benjamin Apr 10 '17 at 00:05
2

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.

Rares
  • 93
  • 1
  • 7
0

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.

TLDR

Use flex attribute instead of flex-grow

Tyler Merle
  • 666
  • 5
  • 7