简体   繁体   中英

How to make <div> to fill the remaining height without using flexbox?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM