@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>