How to force child div to be 100% of parent div's height without specifying parent's height?

Viewed 1223959

I have a site with the following structure:

<div id="header"></div>

<div id="main">
  <div id="navigation"></div>
  <div id="content"></div>
</div>

<div id="footer"></div>

The navigation is on the left and the content div is on the right. The information for the content div is pulled in through PHP, so it's different every time.

How can I scale the navigation vertically so that its height is the same as the content div's height, no matter which page is loaded?

30 Answers

NOTE: This answer is applicable to legacy browsers without support for the Flexbox standard. For a modern approach, see: https://stackoverflow.com/a/23300532/1155721


I suggest you take a look at Equal Height Columns with Cross-Browser CSS and No Hacks.

Basically, doing this with CSS in a browser compatible way is not trivial (but trivial with tables) so find yourself an appropriate pre-packaged solution.

Also, the answer varies on whether you want 100% height or equal height. Usually it's equal height. If it's 100% height the answer is slightly different.

This is a frustrating issue that's dealt with designers all the time. The trick is that you need to set the height to 100% on BODY and HTML in your CSS.

html,body {
    height:100%;
}

This seemingly pointless code is to define to the browser what 100% means. Frustrating, yes, but is the simplest way.

If you don't mind the navigation div being clipped in the event of an unexpectedly-short content div, there's at least one easy way:

#main {
position: relative;
}

#main #navigation {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 10em; /* or whatever */
}

#main #content {
margin: 0;
margin-left: 10em; /* or whatever width you set for #navigation */
}

Elsewise there's the faux-columns technique.

For 2021 Readers:

Try this:

.parent {
  position: relative;

  display: flex;                 // And you will probably need this too.
  flex-direction: row;           // or column.
}

.child {
  position: absolute;
  top: 0;
  bottom: 0;

  align-self: center;            // And you will probably need this too.
}

Here is what I'm working on:

You use CSS Flexbox

.flex-container {
  display: flex;
  background-color: DodgerBlue;
}

.flex-container > div {
  background-color: #f1f1f1;
  margin: 10px;
  padding: 20px;
  font-size: 30px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>  
</div>

<p>A Flexible Layout must have a parent element with the <em>display</em> property set to <em>flex</em>.</p>

<p>Direct child elements(s) of the flexible container automatically becomes flexible items.</p>

</body>
</html>

I might be a bit late to this but I found a work around that might be a bit of a hack. Firstly to give the parent a flex and a height of 100vh

Something like this:

.parent {
   display: flex;
   justify-content: center;
   align-items: center;
   height: 100vh;/* Can be less depends on the container, basically this forces the element to expand */
}

[Referring to Dmity's Less code in another answer] I'm guessing that this is some kind of "pseudo-code"?

From what I understand try using the faux-columns technique that should do the trick.

http://www.alistapart.com/articles/fauxcolumns/

Hope this helps :)

There is a bit of a contradiction in the question's title and the content. The title speaks of a parent div, but the question makes it sound like you want two sibling divs (navigation and content) to be the same height.

Do you (a) want both navigation and content to be 100% the height of main, or (b) want navigation and content to be be same height?

I'll assume (b)...if that is so, I don't think you will be able to do it given your current page structure (at least, not with pure CSS and no scripting). You would probably need to do something like:

<main div>
    <content div>
         <navigation div></div>
    </div>
</div>

and set the content div to have a left margin of whatever the width of the navigation pane is. That way, the content's content is to the right of the navigation and you can set the navigation div to be 100% of the content's height.

EDIT: I'm doing this completely in my head, but you would probably also need to set the navigation div's left margin to a negative value or set it's absolute left to 0 to shove it back to the far left. Problem is, there are many ways to pull this off but not all of them are going to be compatible with all browsers.

I had the same issue, it worked based on Hakam Fostok's answer, I've created a small example, in some cases it might work without having to add display: flex; and flex-direction: column; on the parent container

.row {
    margin-top: 20px;
}

.col {
    box-sizing: border-box;
    border: solid 1px #6c757d;
    padding: 10px;
}

.card {
    background-color: #a0a0a0;
    height: 100%;
}

JSFiddle

What worked for me was adding style={{ display: 'flex', overflowY: "auto" }} to all parents of the child and then style={{ overflowY: "auto" }} to the child itself.

The following code give an ability of setting minimum height to the scroll div and also make it having 100% height of its parent by just using flex.

CSS:

.main {
  display: flex;
  flex-direction: column;
}

.scroll {
  overflow: auto;
  flex: 1 0 50px;
}

HTML:

<div class="main">
  <div class="scroll">
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
  </div>
</div>

This code works perfectly for me

<html>
    <body style="display: flex;">
        <div style="position: absolute; width: 100%; height: 100%; background-color: aliceblue">
            <table style="width: 100%; height: 100%;">
               <tr>
                   <td style="width: 70%; background-color: green"></td>
                   <td style="background-color: red"></td>
               </tr>
            </table>
       </div>
   </body>

The easiest way to do this is to just fake it. A List Apart has covered this extensively over the years, like in this article from Dan Cederholm from 2004.

Here's how I usually do it:

<div id="container" class="clearfix" style="margin:0 auto;width:950px;background:white url(SOME_REPEATING_PATTERN.png) scroll repeat-y center top;">
    <div id="navigation" style="float:left;width:190px;padding-right:10px;">
        <!-- Navigation -->
    </div>
    <div id="content" style="float:left;width:750px;">
        <!-- Content -->
    </div>
</div>

You can easily add a header onto this design by wrapping #container in another div, embedding the header div as #container's sibling, and moving the margin and width styles to the parent container. Also, the CSS should be moved into a separate file and not kept inline, etc. etc. Finally, the clearfix class can be found on positioniseverything.

Related