Contributed by Alejandro Gervasio
It's not unusual for the layout of a Web page to feature multiple columns. Unfortunately, when creating this layout while using general containers, you can end up with columns of uneven height, depending on their content. This looks very unprofessional. Alejandro Gervasio explains a way to keep your column heights even using CSS and javascript.
Introduction
CSS based design is really a powerful approach for most Web developers who consciously keep a website's contents separated from their visual presentation, which improves the site's overall maintenance and flexibility. Without a doubt, these virtues have provided designers with new possibilities for styling and positioning elements within Web documents very easily.
While tables still remain, for good compatibility reasons, the most used technique to define the layout of Web pages, elements have gained considerable territory because they efficiently perform the same task. However, div-based layout exposes some undesirable artifacts when it is applied. Certainly, one of the most common pitfalls encountered when building up a two or more column liquid layout is the inability to give each general containers the same height. It is desirable to achieve a consistent look, but also difficult, because of the dynamic nature of contents to be included in general containers. Due to this issue, many websites present layout columns with uneven heights, which looks very inconsistent to the eyes of visitors.
However, we can do much more to solve this problem. Over the course of this article, I'll show you a simple but powerful approach to match heights for general layout divs, thus eliminating that ugly effect that makes some sites appear quite unprofessional. Using CSS and javascript, we'll find a nice solution without feeling a sense of doom. So, it's time to move on and tame those wild divs!
Say we've set up a generic three-column layout for Web pages, which suits our needs for displaying some dynamic content. We might start writing the code for doing that, defining the basic CSS styles and markup, respectively:
Code: Select all
<html>
<head>
<title>THREE-COLUMN LAYOUT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
margin: 0;
}
#leftcol {
background: #ccf;
float: left;
width: 17%;
}
#content {
width: 65%;
float: left;
background: #ccf;
}
#rightcol {
float: right;
width: 17%;
background: #ccf;
}
</style>
</head>
<body>
<div id="leftcol">
Left Section<br />
Content goes here...
</div>
<div id="rightcol">
Right Section<br />
Content goes here...
</div>
<div id="content">
Content Section<br />
Content goes here...
</div>
</body>
</html>Although we've used floating boxes to achieve the general page layout, other techniques are perfectly valid, such as using absolute positioning and margin specifications. At this point, we have a good three-column design in which each column has the same height. Of course, this case is not a real representation of most Web pages out there. What if we start adding more content to, for example, the left positioned column and a little more to the content ? We might see something similar to the code shown below, derived from the initial example:
Code: Select all
<html>
<head>
<title>THREE-COLUMN LAYOUT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
margin: 0px;
}
#leftcol {
background: #ccf;
float: left;
width: 17%;
}
#content {
width: 65%;
float: left;
background: #ccf;
}
#rightcol {
float: right;
width: 17%;
background: #ccf;
}
</style>
</head>
<body>
<div id="leftcol">
Left Section<br /><br />
Content goes here...<br />
Content goes here...<br />
Content goes here...
</div>
<div id="rightcol">
Right Section<br /><br />
Content goes here...
</div>
<div id="content">
Content Section<br /><br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...
</div>
</body>
</html>Based on the previous examples, suppose we need to add more content to the left column of the Web document, while the content maintains its original height. This simple code will do the trick:
Code: Select all
<html>
<head>
<title>THREE-COLUMN LAYOUT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
margin: 0px;
}
#leftcol {
background: #ccf;
float: left;
width: 17%;
}
#content {
width: 65%;
float: left;
background: #ccf;
}
#rightcol {
float: right;
width: 17%;
background: #ccf;
}
</style>
</head>
<body>
<div id="leftcol">
Left Section<br /><br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...
</div>
<div id="rightcol">
Right Section<br /><br />
Content goes here...
</div>
<div id="content">
Content Section<br /><br />
Content goes here...<br />
Content goes here...
</div>
</body>
</html>Code: Select all
<div>Code: Select all
<html>
<head>
<title>THREE-COLUMN LAYOUT</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body {
margin: 0px;
}
#leftcol {
background: #ccf;
float: left;
width: 17%;
}
#content {
width: 65%;
float: left;
background: #ccf;
}
#rightcol {
float: right;
width: 17%;
background: #ccf;
}
</style>
</head>
<body>
<div id="leftcol">
Left Section<br /><br />
Content goes here...<br />
Content goes here...
</div>
<div id="rightcol">
Right Section<br /><br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...
</div>
<div id="content">
Content Section<br /><br />
Content goes here...
</div>
</body>
</html> Since originally we defined three columns for page layout, the solution will be developed while sticking to the initial example. However, due to the portability of javascript code, it is perfectly applicable to any number of columns which we want to be efficiently matched. Our CSS code closely matches the previous examples, and is listed here:
Code: Select all
<style type="text/css">
body {
margin: 0px;
}
#leftcol {
float: left;
width: 17%;
}
#content {
width: 65%;
float: left;
}
#rightcol {
float: right;
width: 17%;
}
.container {
background: #ccf;
border: 1px solid #000;
}
</style>The HTML markup is nearly identical to the previous examples. We just added the "container" class to each element susceptible to being affected by the javascript function. Here's the code:
Code: Select all
<div id="leftcol" class="container">
Left Section<br /><br />
Content goes here...
</div>
<div id="rightcol" class="container">
Right Section<br /><br />
Content goes here...
</div>
<div id="content" class="container">
Content Section<br /><br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...<br />
Content goes here...
</div>Code: Select all
<script language="javascript">
matchHeight=function(){
var divs,contDivs,maxHeight,divHeight,d;
// get all <div> elements in the document
divs=document.getElementsByTagName('div');
contDivs=[];
// initialize maximum height value
maxHeight=0;
// iterate over all <div> elements in the document
for(var i=0;i<divs.length;i++){
// make collection with <div> elements with class attribute 'container'
if(/\bcontainer\b/.test(divs[i].className)){
d=divs[i];
contDivs[contDivs.length]=d;
// determine height for <div> element
if(d.offsetHeight){
divHeight=d.offsetHeight;
}
else if(d.style.pixelHeight){
divHeight=d.style.pixelHeight;
}
// calculate maximum height
maxHeight=Math.max(maxHeight,divHeight);
}
}
// assign maximum height value to all of container <div> elements
for(var i=0;i<contDivs.length;i++){
contDivs[i].style.height=maxHeight;
}
}
// execute function when page loads
window.onload=function(){
if(document.getElementsByTagName){
matchHeight();
}
}
</script>At first, the function obtains the elements present in the document. The line
divs=document.getElementsByTagName('div');
takes care of that.
Then, the script initializes the array structure for storing all of the elements with class attribute set to "container," followed by the initialization of the variable "maxHeight," which will store the maximum height value found for the divs targeted. Next, the function traverses all of the elements and checks for those with class attribute set to "container." These elements are stored in the array "contDivs" for further processing. The lines below perform that task:
Code: Select all
if(/\bcontainer\b/.test(divs[i].className)){
d=divs[i];
contDivs[contDivs.length]=d;
---
}Code: Select all
if(d.offsetHeight){
divHeight=d.offsetHeight;
}
else if(d.style.pixelHeight){
divHeight=d.style.pixelHeight;
}Code: Select all
<div>Code: Select all
maxHeight=Math.max(maxHeight,divHeight);Summary
In this article we've shown the specific problem of non-matching heights when working with based layout, and hopefully demonstrated a very simple and portable solution. One worthy suggestion about this approach is that if we have a footer section in the page, as is commonly present on most websites, it'd be convenient to initially hide it from view, and once the height matching process have been completed with columns, turn it visible again. After all, those divs are not so wild as they seem to be!
[url="http://www.devarticles.com/c/a/Web-Design-Standards/Matching-div-heights-with-CSS-and-javascript/"]source: DevArticles[/url]

