Height is not correct in flexbox items in Chrome [duplicate]

Solution 1:

@Michael_B explained why Chrome behaves like this:

You gave the body a height: 100%. Then gave its child (.wrapper) a height: 100%. Then gave its child (.content) a height: 100%. So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be a 50% height of body.

However, Firefox disagrees because, in fact, that height: 100% of .content is ignored and its height is calculated according to flex: 1.

That is, Chrome resolves the percentage with respect to the value of parent's height property. Firefox does it with respect to the resolved flexible height of the parent.

The right behavior is the Firefox's one. According to Definite and Indefinite Sizes,

If a percentage is going to be resolved against a flex item’s main size, and the flex item has a definite flex basis, and the flex container has a definite main size, the flex item’s main size must be treated as definite for the purpose of resolving the percentage, and the percentage must resolve against the flexed main size of the flex item (that is, after the layout algorithm below has been completed for the flex item’s flex container, and the flex item has acquired its final size).

Here is a workaround for Chrome:

#content {
  display: flex;
  flex-direction: column;
}
#content::after {
  content: '';
  flex: 1;
}
#half_of_content {
  flex: 1;
  height: auto;
}

This way the available space in #content will be distributed equally among #half_of_content and the ::after pseudo-element.

Assuming #content doesn't have other content, #half_of_content will be 50%. In your example you have a 2 in there, so it will be a bit less that 50%.

html,
body {
  height: 100%;
  margin: 0;
}
#wrapper {
  display: flex;
  flex-flow: column;
  height: 100%;
}
#menu {
  height: 70px;
  background-color: purple
}
#content {
  flex: 1;
  height: 100%;
  background-color: green;
  display: flex;
  flex-direction: column;
}
#content::after {
  content: '';
  flex: 1;
}
#half_of_content {
  flex: 1;
  background-color: yellow;
}
#footer {
  height: 100px;
  background-color: cyan
}
<div id="wrapper">
  <div id="menu">
    1
  </div>
  <div id="content">2
    <div id="half_of_content">2.1</div>
  </div>
  <div id="footer" style="">
    3
  </div>
</div>