Forum Moderators: not2easy

Message Too Old, No Replies

Two column css layout based on nested divs

CSS 100% height nested divs

         

innerg

10:03 am on Nov 20, 2008 (gmt 0)

10+ Year Member



Hi,

I'm new to the forum and have found a lot of good tips.
But I'm trying to find the best way of making a two column css layout based on nested divs.

I've included source code of a test page. (see below)
The problem is that I want my page (wrapper) presented center stage so to speak and the included columns at 100% height. The wrapper needs to scale with it's content.

I found a tip on this site that I need to make my wrapper float so that it will scale but that results in my wrapper not being in the center.

How do I get is back in the center?


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Case</title>
<style type="text/css">
<!--
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: #EFEFEF;
}
#pageWrapper {
float: left; /* if not used the wrapper will not scale with content but makes "margin:0 auto;" not work in the right way */
position:relative; /* needed for footer positioning*/
margin:0 auto; /* center, not in IE5 */
height:auto !important; /* real browsers */
height:100%; /* IE6:treaded as min-height*/
min-height:100%; /* real browsers */
width:400px;
background:#FFFFFF url(../media/blackBar_160.gif) top left repeat-y;
border-left:1px #000000 solid;
border-right:1px #000000 solid;
}
#colomLeft, #colomRight {
overflow: hidden;
float: left;
}
#colomLeft {
width: 25%;
}
#colomRight {
width: 75%;
}
-->
</style>
</head>
<body>
<div id="pageWrapper">
<div id="colomLeft">colomLeft</div>
<div id="colomRight">colomRight</div>
</div>
</body>
</html>

My second question is:

What would be the best way to make the left colomn 100% high so that I can use it's background to create a true second colomn?

innerg

10:50 am on Nov 20, 2008 (gmt 0)

10+ Year Member



Update: I found a solution myself margin-left, margin-right and width in percentages on the Wrapper will give a liquid solution. [still looking for a fixed width for the wrapper solution]

swa66

1:14 pm on Nov 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is little missing to your solution. The advise to make your wrapper a float is the one that's biting you.

But first: try moving all the IE specific stuff in a conditional comment. IE is what is setting you on the wrong foot.

So grab any other browser (e.g. firefox/opera/safari) and take a look at this:
(I'm rolling it back to where you you took the wrong turn):


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/s
trict.dtd">
<html>
<head>
<title>Test Case</title>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #EFEFEF;
}
#pageWrapper {
margin:0 auto;
min-height:100%;
width:400px;
background:#FFFFFF url(1.gif) top left repeat-y;
border-left:1px #000000 solid;
border-right:1px #000000 solid;
}
#colomLeft, #colomRight {
overflow: hidden;
float: left;
}
#colomLeft {
width: 25%;
}
#colomRight {
width: 75%;
}
</style>
</head>
<body>
<div id="pageWrapper">
<div id="colomLeft">colomLeft</div>
<div id="colomRight">replace with really long text</div>
</div>
</body>
</html>

To get it to stretch we need to give it a reason to stretch. Its children all are floated and thus removed from the flow. There is no reason for the parent to stretch, so let's add something after the floats that's not floated and that clears the floats. I typically use a <br> for this, other solutions can be constructed as well (which remain fully in css and don't pollute the html but are harder to understand how they work (search for 'clearfix', but stay away from the hacks they sometimes come with.)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/s
trict.dtd">
<html>
<head>
<title>Test Case</title>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #EFEFEF;
}
#pageWrapper {
margin:0 auto;
min-height:100%;
width:400px;
background:#FFFFFF url(1.gif) top left repeat-y;
border-left:1px #000000 solid;
border-right:1px #000000 solid;
}
#colomLeft, #colomRight {
overflow: hidden;
float: left;
}
#colomLeft {
width: 25%;
}
#colomRight {
width: 75%;
}
.clear {
clear:both;
}
</style>
</head>
<body>
<div id="pageWrapper">
<div id="colomLeft">colomLeft</div>
<div id="colomRight">replace me with a really long text</div>
<br class="clear">
</div>
</body>
</html>

Your secodn question: since your wrapper has no explicitly set height, there really is no way to have the children use 100% of its height. The faux-columns trick with the background will have to do I'm afraid.

So that being settled, on to the other standards compliant browsers just to make sure I didn't use something only firefox supports or has as a feature.

Safari: check
Opera: check

On to the more difficult browsers, set see what curve balls they have up their sleeves for us:

IE7: surprisingly has no oddities for us, so no conditional comment needed to fix it.

IE6 will be willing to play with us I hope, but aside of the expected lack of support for min-height there is little to wrong with it today (that's a bit uncommon to be honest)

As you already know: min-height can be simulated with height in IE6


<!--[if lte IE 6]>
<style type="text/css">
#pageWrapper {
height:100%;
}
</style>
<![endif]-->

We got lucky here: #pagewrapper already has the "hasLayout" property due to it having a fixed width. Otherwise there would have been more work.

Using the conditional comment makes it much easier to avoid giving these dirty workarounds to other browsers such as the future IE8 which Microsoft promised would be standards compliant when released.

A final thing: try using names for you id-s that are future proof: if you want you menu not on the left, but over the top, you column left and column right will not make much sense any longer.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/s
trict.dtd">
<html>
<head>
<title>Test Case</title>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #EFEFEF;
}
#pageWrapper {
margin:0 auto;
min-height:100%;
width:400px;
background:#FFFFFF url(1.gif) top left repeat-y;
border-left:1px #000000 solid;
border-right:1px #000000 solid;
}
#menu, #content {
overflow: hidden;
float: left;
}
#menu {
width: 25%;
}
#content {
width: 75%;
}
.clear {
clear:both;
}
</style>
<!--[if lte IE 6]>
<style type="text/css">
#pageWrapper {
height:100%;
}
</style>
<![endif]-->
</head>
<body>
<div id="pageWrapper">
<div id="menu">colomLeft</div>
<div id="content">replace me with a really long text</div>
<br class="clear">
</div>
</body>
</html>

If you want to, you can remove the <br> and the clear class and replace it with this:


#pageWrapper:after {
content: ".";
display:block;
height:0;
overflow: hidden;
clear:both;
visibility:hidden;
}

It does create a bit of an artifact in firefox3 though (not in safari nor opera)

innerg

9:20 am on Nov 22, 2008 (gmt 0)

10+ Year Member



Hi swa66,

Thank you for the super reply. I didn't have the time to fully explore it yet. I've read it and got it all. I will try all this out this weekend. Just wanted to thank you so far!