hannebaumsaway
hannebaumsaway

Reputation: 2734

Div not exactly equalling height of parent div with inherit value

I have 3 divs inside a parent div, intended to be arranged like so:

 ______________________________________
|                                      |
|                HEADER                |
|______________________________________|
 ____   _______________________________
|    | |                               |
|    | |                               |
|    | |                               |
|    | |                               |
| N  | |                               |
| A  | |            CONTENT            |
| V  | |                               |
| -  | |                               |
| B  | |                               |
| A  | |                               |
| R  | |                               |
|    | |                               |
|    | |                               |
|____| |_______________________________|

The #header is fixed height, so I'm having no issues with it.

However, the #content div's, well, content, is dynamic, depending on the page that is loaded. I want #nav-bar to match the height of #content at all times, but I haven't been able to manage it.

I want the min-height of #content and #nav-bar to be 100% of the screen height (so they take up the full height of the screen at minimum at all times), but then as #content grows beyond that, I want #nav-bar to grow accordingly.

I've gotten #nav-bar's height to grow, but not at exactly the same value as #content, so their heights are still mismatched.

Here is the relevant code I have in place, and the actual page in question is here.

HTML:

<div id='container'>
    <div id='center-panel'>
        <div id='top-banner'></div>
        <div id='nav-bar'>
            <?php
            echo get_nav_list();
            ?>
        </div>
        <div id='header'><span id='fact-tag'>current points leader</span><span id='fact-value'>4</span></div>
        <div id='content'>Lorem ipsum...
        </div>
    </div>
</div>

CSS:

html, body {
    background-color: #ccc;
    min-height: 100%;
    margin: auto;
    font-family: 'Noto Sans', 'Tahoma', sans-serif;
    font-size: 12pt;
    color: #666;
}

#container {
    height: 100%;
    overflow: scroll;
}

#center-panel {
    margin-left: auto;
    margin-right: auto;
    width: 800px;
    background-color: #fff;
    min-height: 100%;
}

#header {   /*top bar*/
    height: 33px;
    max-height: 33px;
    text-align: right;
    color: #aaa;
    padding: 0px 15px 0px 160px;
    font-size: 18pt;
    border: 2px dashed blue;
}

#header span#fact-tag {
    font-weight: 700;
}

#header span#fact-value {
    display: inline-block;
    min-width: 40px;
    background-color: #ccc;
    margin-left: 10px;
    color: #444;
    padding: 0px 3px 0px 3px;
}

#nav-bar {  /*left bar*/
    float: left;
    width: 110px;
    text-align: center;
    height: inherit;
    font-family: 'Oxygen', 'Tahoma', sans-serif;
    padding: 33px 0px 0px 0px;
    border: 2px dashed red;
}

#nav-bar ul {   /*main menu*/
    list-style-type: none;
    text-align: left;
    font-size: 10pt;
    padding: 0px;
    margin: 0px;
}

#nav-bar > ul > li {    /*main menu item*/
    min-height: 35px;
    background-color: #444;
    color: #ccc;
    border-left: 6px solid #444;
    border-bottom: 3px solid #666;
    cursor: pointer;
}

#nav-bar ul > li > ul { /*sub-menu*/
    display: none;
}

#nav-bar ul > li > ul > li {    /*sub-menu item*/
    min-height: 25px;
    background-color: #555;
    border-bottom: 3px solid #444;
    font-size: 10pt;
    cursor: pointer;
}

#nav-bar ul > li > ul > li > ul > li {  /*third-level menu item*/
    border: none;
    min-height: 10px;
    font-size: 8pt;
    cursor: pointer;
}

#content {  /*central content area*/
    padding: 60px 45px 30px 160px;
    border: 2px dashed green;
}

Javascript:

$('#nav-bar ul li').on('click', function() {
    $(this).css('border-left-color', '#ad9557').siblings().css('border-left-color', '#666');
    $(this).children().slideDown('fast');
    $(this).siblings().children('ul').slideUp('fast');
});

$('#nav-bar').css('height', $('#container').height());

Upvotes: 0

Views: 2552

Answers (5)

Joey
Joey

Reputation: 1679

It's not a great idea to use display: table or the float property for layout. Tables are for tabular data, and floats are designed to allow text to flow around them in paragraphs. You can easily solve this problem by assigning position: absolute to your #navbar element and adjusting a few properties elsewhere to make the layout act as desired.

#navbar {
    padding: 33px 0px 0px 0px;
    float: left;
}

#navbar {
    position: absolute;
    height: 100%;
}
#container {
    position: relative;
}
#nav-bar ul {
    margin: 33px 0 0;
}

I changed the margin on #nav-bar ul because the navbar's padding was causing it to increase in height past the page's limit. If you need more info on absolute positioning, further reading can be done here.

This solution will work without javascript and will work on almost all browsers.

Edit: since you want the page to change depending on the height of the user's screen and the height of the #content div, you can use a jQuery one-liner to check to see if the #content div is tall enough or not.

($('#content').offset().top+$('#content').height() < $(window).height())?($('#content').height($(window).height()-90-$('#content').offset().top)):null;

This code is equivalent to saying "If the content div's height and offset is below the height of the window, increase the content div's height to exactly the height it needs to be to fill the window, otherwise do nothing."

Upvotes: 2

robyaw
robyaw

Reputation: 2311

My attempt as a jsFiddle. The bulk of the changes are in the CSS and HTML; the actual nav height setting is done almost identically to your posted code:

$('#nav-bar').css(
    'height',
     $('#content-container').height() - parseInt($('#nav-bar').css('border-width'), 10) * 2);

where parseInt($('#nav-bar').css('border-width'), 10) * 2 is done to take into account the demo borders on #nav-bar; your solution probably won't need this in.

Upvotes: 0

Derek Henderson
Derek Henderson

Reputation: 9706

If you don't have to support IE8, simply use calc:

#nav-bar,
#content {
    min-height: calc(100% - 33px); // 33px is height of header, of course
}

If you do have to support IE8, just set it with jQuery, as you're already using it:

$('#nav-bar, #content').css('min-height', ($(window).height() - 33) + 'px');

And if you want '#nav-bar' always to match the height of '#content', add this:

$('#nav-bar').css('height', $('#content').height() + 'px');

Another possibility is to use flex-box.

Upvotes: 0

Nagarajan A
Nagarajan A

Reputation: 89

Try this:

Just add '!important':

$('#nav-bar').css('height', ($('#container').height()+'!important'));

Upvotes: 0

nickford
nickford

Reputation: 792

Use display:table, that will force the height of the two columns to match, regardless of which is bigger.

Upvotes: 1

Related Questions