Larpee
Larpee

Reputation: 820

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.

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>

Upvotes: 12

Views: 45022

Answers (4)

Simon_Weaver
Simon_Weaver

Reputation: 145880

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?

Upvotes: 14

Rares
Rares

Reputation: 93

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.

Upvotes: 2

Michael Benjamin
Michael Benjamin

Reputation: 371003

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

Upvotes: 13

Tyler Merle
Tyler Merle

Reputation: 696

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

Upvotes: 1

Related Questions