I have a html layout like this:
,-------------.
|,-----------.|
|| child 1 ||
|`-----------'|
|,-----------.|
|| child 2 ||
|| ||
|| ||
|| ||
|| ||
|`-----------'|
`-------------'
The container is given a height value, say 100vh
, and child 1
has a fixed height. I want the child 2
to automatically fill the remaining height.
I know there is a flexbox solution:
.container {
display: flex;
flex-direction: column;
}
.child-1 {
flex-shrink: 0;
flex-grow: 0;
}
.child-2 {
flex-grow: 1;
}
The solution works as alone, but if I want a third child child 3
inside child 2
with a height: 100%
, it fails. I need to make child 2
flex and set child 3
to flex-grow: 1
.
This kind of flex-inheriting become really frustrating as the nesting goes deeper. Also it violates "Seperation of Concern" since the DOM structure only works when all the nodes are properly set to display: flex
.
Below is jsfiddle demonstrating the problem.
html, body { margin: 0; } div { width: 100%; } .container { height: 100vh; display: flex; flex-direction: column; } .child-1 { height: 50px; flex-shrink: 0; flex-grow: 0; } .child-2 { flex-grow: 1; } .child-3 { height: 80%; } /* irrelevant styles like background-color etc. */ .container.irrelevant { width: 100px; background: green; float: left; margin-right: 20px; } .child-1.irrelevant { background: red; } .child-2.irrelevant { background: magenta; } .child-3.irrelevant { background: yellow; }
<div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2<br> Seems like it works </div> </div> <div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2 <div class="child-3 irrelevant"> But it doesn't, child 3 should fill 80% height of the child 2. </div> </div> </div>
Oh you can use calc for this. Something like this;
.child-2 { height: calc(100vh - 100px); }
Assuming the fixed height for .child-1
is 100px
.
If you want something more dynamic use @patelarpan's solution, but this is quick and easy (and not dirty).
Add height: 100%
to child 2.
you can use CSS grid
also but it's not supported in all browsers.
html, body { margin: 0; } div { width: 100%; } .container { height: 100vh; display: flex; flex-direction: column; } .child-1 { height: 50px; flex-shrink: 0; flex-grow: 0; } .child-2 { flex-grow: 1; height: calc(100% - 50px); /* add this line */ } .child-3 { height: 80%; } /* irrelevant styles like background-color etc. */ .container.irrelevant { width: 100px; background: green; float: left; margin-right: 20px; } .child-1.irrelevant { background: red; } .child-2.irrelevant { background: magenta; } .child-3.irrelevant { background: yellow; }
<div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2<br> Seems like it works </div> </div> <div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2 <div class="child-3 irrelevant"> But it doesn't, child 3 should fill 80% height of the child 2. </div> </div> </div>
It seems that .child-3
cannot properly calculate parents height unless it has set flex-basis
. So you can fix this by using flex: 1
on child-2
DEMO or by just adding flex-basis: 0%
DEMO which is the same thing that the browser will do if you use flex: 1
.
html, body { margin: 0; } div { width: 100%; } .container { height: 100vh; display: flex; flex-direction: column; } .child-1 { flex: 1; height: 50px; flex-shrink: 0; flex-grow: 0; } .child-2 { flex: 1; } .child-3 { height: 80%; } /* irrelevant styles like background-color etc. */ .container.irrelevant { width: 100px; background: green; float: left; margin-right: 20px; } .child-1.irrelevant { background: red; } .child-2.irrelevant { background: magenta; } .child-3.irrelevant { background: yellow; }
<div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2<br> Seems like it works </div> </div> <div class="container irrelevant"> <div class="child-1 irrelevant"> Child 1 </div> <div class="child-2 irrelevant"> Child 2 <div class="child-3 irrelevant"> But it doesn't, child 3 should fill 80% height of the child 2. </div> </div> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.