Liquid Column Display Layout – Part II
In my earlier post I had discussed about the designing the liquid 3 column display layout. While developing the structure I had some problem with the column heights. Depending upon the contents length of those columns varies. I have declared the height property as auto in the css. I could have declared them with some specific pixel value to make the columns of equal length. But if you consider your pages to contain dynamic content generated by server side scripting then this technique may fail. Particularly in Internet Explorer the data part may be extended beyond the columns, which could make the structure awful. So I was in need to find some other solutions for that purpose.
I thought of using some JavaScript to make all the columns height equal. The algorithm to do this is very simple. Calculate the max height among three columns and assign it for all the columns. So first I introduced three different IDs for these three columns to access the properties of those columns using Javascript document.getElementById() method. So I changed the HTML code as follows:
[code lang=”html4strict”]
The text….
[/code]
contentDiv_left for the left column, contentDiv_mid for the middle column and contentDiv_right for the right one. contentDiv ID for the container div for these 3 columns.
Then my job was to find out the maximum height of these 3 columns. First I used offsetHeight property for this purpose. Calculate the max height and assign it to all the 3 columns style.height property. While testing the code I found it was working fine with Internet Explorer. In case of FireFox or Opera or Netscape browsers the code was malfunctioning, more specifically it was unable to find out the height of those columns using offsetHeight property. So I started looking for bug. While doing that I found out offsetHeight is a readonly property of the DHTML Object model introduced by MSIE. But is not part of any W3C specification or technical recommendation. So incase of browsers like FF or Opera it won’t work. So I started looking for some alternate property to find out the heights of those columns. There are some properties which didn’t worked for me are element.style.height, element.style.max-height etc. I tried with
window.getComputedStyle(element,null).getPropertyValue(“height”).
As window.getComputedStyle method can be used to get the styles of an element that are not set using the style attribute or with JavaScript. But it didn’t work too. Finally I worked out with this method :
document.defaultView.getComputedStyle(element, null).getPropertyValue(“height”).
The document.defaultView returns a reference to the default AbstractView for the document. This document.defaultView is part of the DOM Level 2 DocumentView interface. This interface is not a mandatory part of Document Object Model Level 2 Core specification. DOM of IE doesn’t implement this but DOM in mozilla supports this. So I put a browser check and utilized the above method for browser like FF, Opera and offsetHeight propery for IE. Hence my code looks like this :
[code lang=”javascript”]
function checkBrowserComponent() {
var ua = navigator.userAgent.toLowerCase();
//var p = ua.indexOf(‘msie’);
//alert(p);
if(ua.indexOf(‘msie’)!=-1) {
return “ie”;
}
else if(ua.indexOf(‘firefox’)!=-1) {
return “ff”;
}
return “oth”;
}
function maintainMaxColHeight(pHeight) {
var defMaxHeight = 650;
var elmMain = document.getElementById(“contentDiv”);
var elmLS = document.getElementById(“contentDiv_leftSingle”);
var elmL = document.getElementById(“contentDiv_left”);
var elmM = document.getElementById(“contentDiv_mid”);
var elmR = document.getElementById(“contentDiv_right”);
var ua = checkBrowserComponent();
if(ua == ‘ff’) {
if(elmLS != null) {
//alert(elmLS);
var lh = document.defaultView.getComputedStyle(elmLS, null).getPropertyValue(“height”);
lh = parseInt(lh);
if(lh > defMaxHeight) {
defMaxHeight = lh;
}
}
else {
var lh = document.defaultView.getComputedStyle(elmL, null).getPropertyValue(“height”);
lh = parseInt(lh);
if(lh > defMaxHeight) {
defMaxHeight = lh;
}
var mh = document.defaultView.getComputedStyle(elmM, null).getPropertyValue(“height”);
mh = parseInt(mh);
if(mh > defMaxHeight) {
defMaxHeight = mh;
}
}
var rh = document.defaultView.getComputedStyle(elmR, null).getPropertyValue(“height”);
rh = parseInt(rh);
if(rh > defMaxHeight) {
defMaxHeight = rh;
}
}
// this sets the height manually
if(pHeight > defMaxHeight) {
defMaxHeight = pHeight;
}
else if(ua == ‘ie’) {
//elmL.currentStyle
if(elmLS != null) {
var lh = elmLS.offsetHeight;
if(lh > defMaxHeight) {
defMaxHeight = lh;
}
}
else {
var lh = elmL.offsetHeight;
if(lh > defMaxHeight) {
defMaxHeight = lh;
}
var mh = elmM.offsetHeight;
if(mh > defMaxHeight) {
defMaxHeight = mh;
}
}
var rh = elmR.offsetHeight;
if(rh > defMaxHeight) {
defMaxHeight = rh;
}
}
if(elmLS != null) {
elmLS.style.height = defMaxHeight+”px”;
}
else {
elmL.style.height = defMaxHeight+”px”;
elmM.style.height = defMaxHeight+”px”;
}
elmR.style.height = defMaxHeight+”px”;
elmMain.style.height = defMaxHeight+”px”;
}
[/code]
I called this function maintainMaxColHeight() in onLoad within body tag.
After adding this script the page now looks like :
Now what’s the conclusion? I think in case of maintaining the equal height for the columns there are 2 options. First one is to put a fixed pixel value as height property in css for all the columns. Next one is implementing this JavaScript code. For this second option browser should support JavaScript (I believe most of the current browsers do so). In my opinion if a website is designed using liquid column display layout where all pages contain static information, first option will the best for that case. I always prefer to avoid unnecessary script execution for web pages as it reduces the page download and display time. The second option is best for websites containing dynamic information (like my project).
The project where I have implemented this layout is near to completion. Still it is not fully online I won’t be able to show you. I need to wait a little more to show you the live example.