SystemParadox
SystemParadox

Reputation: 8646

CSS flex-basis: 0% has different behaviour to flex-basis: 0px

According to MDN, the flex: 1 shorthand should set flex-basis: 0. However, it actually sets flex-basis: 0%, and even more surprisingly this has different behaviour.

In the example below, I expect div.middle to shrink and scroll because it's been given overflow-y: auto and flex: 1, which should also imply flex-basis: 0. But it doesn't - the entire body scrolls instead because it refuses to shrink. If you uncomment the explicit flex-basis: 0, it then works correctly.

body {
  text-align: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
}
.outer {
  min-height: 100%;
  display: flex;
  background: #99f;
  flex-direction: column;
}
.middle {
  background: #f99;
  flex: 1;
  /*flex-basis: 0;*/
  overflow-y: auto;
}
<div class='outer'>
  <div class='top'>top</div>
  <div class='middle'>
    A
    <div style='height:800px'></div>
    B
  </div>
  <div class='bottom'>bottom</div>
</div>

I tested this in both Chrome 84.0 and Firefox 68.11.0esr and they both have the same unexpected behaviour.

  1. Why does flex-basis: 0% differ from flex-basis: 0?
  2. Why does flex: 1 set flex-basis: 0% instead of flex-basis: 0?

Upvotes: 8

Views: 3062

Answers (1)

Temani Afif
Temani Afif

Reputation: 273626

The issue is related to the usage of percentage. Using 0 or 0px is trivial since you will set the initial height to be 0 and then the element will grow to fill the remaining space.

Using N% is a different story because in this case you are setting the initial height to be based on the parent height.

Percentages: relative to the flex container’s inner main size ref

In your case, the flex container doesn't have any explicit size since your are using only a min-height definition so we cannot resolve the percentange value and it will fail to auto

If you change the min-height with height both will behave the same:

body {
  text-align: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0;
}
.outer {
  height: 100%;
  display: flex;
  background: #99f;
  flex-direction: column;
}
.middle {
  background: #f99;
  flex: 1;
  /*flex-basis: 0;*/
  overflow-y: auto;
}
<div class='outer'>
  <div class='top'>top</div>
  <div class='middle'>
    A
    <div style='height:800px'></div>
    B
  </div>
  <div class='bottom'>bottom</div>
</div>

Why does flex: 1 set flex-basis: 0% instead of flex-basis: 0?

Check this: What does flex: 1 mean? Not all the browser are setting flex:1 to be equal to flex:1 1 0

Upvotes: 10

Related Questions