Matching div heights with CSS and JavaScript

Get Help With All Aspects of Web Design & Design Software

Moderators: Moderator, Global Moderator

Post Reply
Tami
Administrator
Administrator
Posts: 10892
Joined: Sun Apr 25, 2004 1:05 pm

Matching div heights with CSS and JavaScript

Post by Tami »

Matching div heights with CSS and javascript 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]    <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>[/code] As we can see in the above example, a simple three-column layout has been defined using the \"float\" property to properly position each container element in the document. Following the document structure, the \"leftcol\" element is floated to the left side, the \"rightcol\" is similarly floated to the right side, and finally, in a similar fashion, the \"content\" has been floated to the left, sticking to the \"leftcol\" element, being displayed nearly the center of the screen. Also, widths for each element have been defined by percentages. It\'s simple enough and effective to use in liquid designs. 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]    <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>[/code] This spoils the party! As we can appreciate, heights for each element won\'t be the same and columns will be unequally displayed. We might end up with a visual output like this: [attachment=644:attachment] Certainly, this is not what we want for our rendered Web pages, right? Those elements are causing big headaches, and making our pages look pretty unprofessional. What\'s more, other possible variations to the example might be feasibly implemented. Let\'s see them in turn, in order to illustrate each of them. 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]    <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] Once again, unfortunately, elements will be unequally displayed in the document, resulting in the following undesirable visual output: [attachment=645:attachment] The last remaining case to be analyzed, which certainly would render non-matching [code]<div>[/code] heights for the Web document\'s columns, will occur when additional content is included in the right column. This situation might be represented with the following code, based on the previous examples: [code]    <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>  [/code] As we\'ve done with the above samples, the visual output for this code is illustrated below: [attachment=646:attachment] Consciously, we\'ve taken a detailed look at the most common cases where the columns and content sections are displayed with different heights, according to the content that each element should contain. Indeed, the problem must be quickly tackled, preventing its ugly side effects, when we\'re utilizing elements for page layout. So, how can we make column heights match properly, showing a very polished and consistent look, independently from the content generated? Fortunately, the answer is quite simple: a javascript function that will set heights to the same value, achieving the desired matching height. Now, let\'s take a look at the javascript code. 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]    <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>[/code] As you can see, we\'ve defined the three main columns originally presented, and an additional \"container\" class that will be used to hook up a style for each column, if we really wish to do it. In the example, I\'ve chosen to give a background color and borders. However, this is not mandatory at all. Also, the \"container\" class will provide us with an easy way to identify the columns to be targeted by the script within the markup. 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]    <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] Nothing unexpected, is it? Finally, we list the javascript code, necessary to perform column height matching. It is as follows: [code]    <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>[/code] As we usually do, let\'s break down the code to give a detailed explanation about each section of it: 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]    if(/\bcontainer\b/.test(divs[i].className)){                    d=divs[i];                    contDivs[contDivs.length]=d;    ---    }[/code] Now, let\'s explain the key section of the script. For each targeted element, we need to calculate its height, in order to determine which has the greatest height value. To do that, we\'re using alternatively the offsetHeight and pixelHeight properties in order to determine the height value expressed in pixels for an element. This snippet performs the above mentioned process: [code]    if(d.offsetHeight){    divHeight=d.offsetHeight;    }    else if(d.style.pixelHeight){         divHeight=d.style.pixelHeight;    }[/code] Finally, the code determines the greatest [code]<div>[/code] height of all of the elements analyzed, with the following expression: [code]maxHeight=Math.max(maxHeight,divHeight);[/code] Once the function has determined the greatest height value of all the elements, the only thing left to do is assign that value to each container height, performing the needed matching for height values. The last thing to do is wrap the whole code into a javascript function that will be executed when the page finishes loading. After the execution of the script, the visual output for the example might look similar to this: [attachment=647:attachment] Definitively, that looks a lot better than the previous cases, don\'t you agree? We\'ve implemented height matching with the columns present in the Web page. That\'s pretty good! 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]
Image

[color=\"#41211C\"]It takes years to build up trust and only seconds to destroy it

[/color]
Post Reply

Return to “Web Design Principles”