APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

Equal height CSS columns with filler text


2007/12/02

If you search for "column alignment" or "css columns", you'll probably eventually end up at In search of the One True Layout at positioniseverything.net. That's great stuff, but it is not what I wanted.

I want to fill the left hand column with text so that it matches the height (the page length) of the main text in the right hand column. I can't always do that - for one thing, I may not have enough filler text, because the text I want is links to related content (that is, other articles related to the content in the main text). Also, there's a certain amount of content I want on the left hand side no matter how short the right hand side is. So I can't always be perfect, but I can get everything aligned most of the time.

The problem, of course, is knowing when to stop writing text in the left column. At some point, the length of that column will exceed the text already displayed in the right column, and that produces an unattractive page. I could just write a few things in the left side, but that can leave lots of wasted space if the right hand side is long, and while that's not extremely ugly, it is unused space that I'd like to fill with content.

The problem with client side Javascript is that it can't read files on the webserver. You wouldn't want it to be able to, because it is running from the browser of the person reading your page and could be modified by them. Perl running on your server through a SSI (Server Side Include) of course can read files, so we'll use that to create Javascript code. If that confuses you, you probably just need to play with this to see it in action.

This is the Perl code that produces the Javascript that aligns the left column:

print <<EOF;
<script type="text/javascript">
function getht(h) {
 var x=0;
 while(h) {
   x += h.offsetTop;
   h= h.offsetParent;
  }
 return x;
}
 var nb =document.getElementById("nearbottom");
 var nbht=getht(nb);
 var cht=0;
 var leftside =document.getElementById("leftside");
 var leftheight=getht(leftside);
 var filler=new Array();
EOF
for ($x=0;$x < 50; $x++) {
print qq(filler[$x]=');
randompage();
print qq(';\n);
}
print <<EOF;
 for (var x=0; x < 50; x++) 
 {
if (nbht > leftheight ) {
   id='p' + x;
   var pfiller=document.createElement("p");
   pfiller.id=id;
   // use next line if you want to see the variables for debugging
   // pfiller.innerHTML=filler[x] + " " + leftheight + " " + nbht;
   pfiller.innerHTML=filler[x] + " ";
   leftside.appendChild(pfiller);
   leftheight=getht(document.getElementById(id));
}

 }
document.write('<br /></div>');
</script>
EOF
 

The "randompage()" is a subroutine that returns randomly sorted related pages - I'm not showing that here, but it should be easy to imagine what it does. If it has nothing more to return, it returns "<br />". After this runs, the page is going to contain something like this:

<script type="text/javascript">
function getht(h) {
 var x=0;
 while(h) {
   x += h.offsetTop;
   h= h.offsetParent;
  }
 return x;
}
 var nb =document.getElementById("nearbottom");
 var nbht=getht(nb);
 var cht=0;
 var leftside =document.getElementById("leftside");
 var leftheight=getht(leftside);
 var filler=new Array();
filler[0]='<a href="http://aplawrence.com/Words2005/2005_07_30.html">Archiving All Email </a>';
filler[1]='<a href="http://aplawrence.com/Security/fake_blacklists.html">Fake blacklists? </a>';
..
filler[48]='<a href="http://aplawrence.com/Security/web-ip-filter.html">Web site IP filtering </a>';
filler[49]='<a href="http://aplawrence.com/MDesrosiers/pci_dss.html">PCI DSS and ISO 17799 </a>';
 for (var x=0; x < 50; x++) 
 {
if (nbht > leftheight ) {
   id='p' + x;
   var pfiller=document.createElement("p");
   pfiller.id=id;
   // pfiller.innerHTML=filler[x] + " " + leftheight + " " + nbht;
   pfiller.innerHTML=filler[x] + " ";
   leftside.appendChild(pfiller);
   leftheight=getht(document.getElementById(id));
}

 }
document.write('<br /></div>');
</script>
 

What that does is fill an array of 50 items that can potentially be used to fill space. In the right side main text, the last paragraph is marked with an id tag: <p id="nearbottom>. The Javascript finds the position of the "nearbottom" paragraph to start with, and then starts creating new paragraphs filled with the text randompage() supplied. The code checks the position of each new paragraph, and stops writing them once that position reaches that of "nearbottom".

Of course the filler material could be anything: pictures, random jokes, whatever: even more Javascript scripts (though that gets really hard because of quoting).

cartoon

Keep in mind that I am no Javascript expert. I tested this on Firefox, Safari, Opera and Internet Explorer 7, but there may very well be places it will not work, and failure to work will either produce nothing at all or 50 lines of text no matter where "nearbottom" is. You do need to quote " ' "'s in your filler text returned by random() or whatever function you call.

If you are going to play with this, I strongly suggest using Firefox because of its built in Javascript console. That will let you see Javascript coding errors which are usually caused by quoting mistakes when you are producing the script from another program as we are here. Without that console, it can be really hard and very frustrating to find the most simple problems.

The only problem I have with this is that I can't use the W3C validator with this code. I don't understand why yet, but W3C seems to think that the "filler[0]=" lines are HTML that should be checked.. I haven't figured out why, but it's surely my mistake somewhere..



Got something to add? Send me email.





(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Equal height CSS columns with filler text


8 comments



Increase ad revenue 50-250% with Ezoic


More Articles by

Find me on Google+

© Anthony Lawrence







Sun Dec 2 16:23:33 2007: 3287   TonyLawrence

gravatar
So how about a reader challenge?

First person to figure out why W3C won't validate and provide a workaround gets $50 by Paypal. Fair enough?
Don't post your solution as a comment. Send it by email (see Contact Info on the menu links above).



Mon Dec 3 01:52:22 2007: 3288   TonyLawrence

gravatar
Well, I've found a way around it:

Wrapping the Javascript in faux comments makes W3C happy..

<!-- this shouldn't be necessary
EOF
for ($x=0;$x < 100; $x++) {
print qq(filler[$x]=');
randompage();
print qq(';\n);
}
print <<EOF;
// -->

etc..

Wouldn't have thought I needed to do that.



Mon Dec 3 11:50:43 2007: 3289   TonyLawrence

gravatar
And then finally I realized that this doesn't need to be dynamic for my use: the only time the filler content changes is when I add new content, so I can regenerate scripts at that time. For example, this page now calls "Web.js" . That unconfuses W3C .

I added random pictures and scrambled the links; you can see the current version by getting aplawrence.com/Web.js in your browser (well, Firefox, anyway).



Mon Dec 3 16:32:49 2007: 3290   Niall


If you ever switch to XHTML:

<script type="text/javascript">
/* <![CDATA[ */
... javascript ...
/* ]]> */
</script>







Mon Dec 3 18:13:17 2007: 3291   TonyLawrence

gravatar
It is XHTML now.. good idea, I forgot about that!



Thu Dec 6 21:54:55 2007: 3298   MikeHostetler


I'm a huge fan of YUI grids -- it's CSS-based, properly tested on all name-brand browsers, and well-documented and supported. Heck, you don't even had to host the files yourself!

(link)






Thu Dec 6 21:58:52 2007: 3299   TonyLawrence

gravatar
I certainly agree (if you look at "View Source" you'll see I use them here), but how could they help with this??



Thu Apr 15 13:16:00 2010: 8422   w3cvalidation

gravatar


Nice information, I really appreciate the way you presented.Thanks for sharing..

------------------------
Kerio Samepage


Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us





May you live long enough to regret your opinions - (Tony Lawrence)

The primary duty of an exception handler is to get the error out of the lap of the programmer and into the surprised face of the user. (Verity Stob)












This post tagged: