swanky gorgon
swanky gorgon

Reputation: 103

How can I make the height behaviors of table tag and div tag work the same?

I am trying to achieve a typical layout which has a Header, Middle and Footer area. I especially want to make sure that the Footer is never any higher than the bottom of the visible screen. Put another way: when a Middle has short content, the Footer should be exactly at the bottom of the page; when a Middle has tall content, the Footer can be below the fold and must be below the bottom of the Middle content.

One additional constraint is that I am working with a ton of existing HTML which I cannot change wholesale -- I can mostly only change the CSS involved. The Middle area is sometimes a table tag and sometimes a div. And therein lies the problem -- div and table behave differently here (in latest Chrome, Safari & FF).

What CSS can I use that will work for both table and div (and that works in a reasonable swath of desktop browsers, lets say anything from the last 3 years)?

For the < table > based page, the css is set up like so:

Which has the desired effect on < table >:

However, for < div > it fails. The "pulling" effect is the same and works well. But the height of the div seems to be the height of the Header plus the height of the window.

I've tried tweaking the box model of different pieces; I've tried "display: table;" on the div.

Here is some HTML which demonstrates the issue. Just remove the "display: none;" for div.middle or table.middle to see the behavior for each.

<!DOCTYPE html>
<html>
<head>
    <style>
        html, body {
            margin: 0;
            height: 100%;
            width: 100%;
        }
        .header { 
            width: 90%;
            height: 100px; 
            background: rgba(0,255,0,.25); 
        }
        table.middle { 
            display: none; 
            box-model: border-box; 
            height: 100%;
            margin-bottom: -20px;
            margin-top: -100px;
            padding-top: 100px;
            width: 100%;
            background: rgba(255,0,0,.25); 
        }
        div.middle { 
            display: none;
            box-model: border-box; 
            height: 100%;
            margin-bottom: -20px;
            margin-top: -100px;
            padding-top: 100px;
            width: 100%;
            background: rgba(255,0,0,.25); 
        }
        .footer {
            width: 90%;
            height: 20px;
            background: rgba(0,0,255,.25); 
        }
    </style>
</head>
<body>
    <div class="header">
        header
    </div>
    <table class="middle"><tr><td>
        body
    </td></tr></table>
    <div class="middle">
        body
    </div>
    <div class="footer">
        footer
    </div>
</body>
</html>

Upvotes: 0

Views: 195

Answers (1)

brentonstrine
brentonstrine

Reputation: 22742

[UPDATED ANSWER]

I see what's happening here. Your div has padding-top:100px which makes its total height 100% + 100px. Your table has the same thing, but the table does weird things so that it doesn't cause the issue. E.g. the table always stretches to fill the space in a way that the div won't. Note how the word "body" is centered with your table but not with your div.

If you remove the padding-top:100px; from the div CSS, it fixes the issue, except then your middle area overlaps the header. Since you can't edit your HTML, you can use CSS to give whatever the first element in the main section a margin-top of 100px, to put that buffer back in there without adding to the height of the div. Something like this should work:

div.middle:first-child{
   margin:top: 100px;
}

[OLD ANSWER]

Here's a JSFiddle with my solution. Basically, wrap the whole thing in a container div,

<div class="container">
   [all your HTML]
</div>

...and give it a min-height of 100%. This way the container will be 100% when the content is small, but will expand when the content is larger than 100%.

.container { 
    min-height: 100%;
    position: relative;
}

You also make it position:relative because you have to position the footer absolutely to stick to the bottom edge of it no matter what:

.footer {
    position: absolute;
    bottom: 0px;
}

See my JSFiddle to see the example--it works with both your div and your table.

PS: You had them with 100% height, but a better emulation of large/small content is to use pixels, say toggle it between 60px and 600px. Also, I removed your margin-bottom:-20px from them because they weren't needed anymore, since making the footer absolute removes it from the flow of the document.

Upvotes: 1

Related Questions