Sunday, March 30, 2008

Holy Grail of 3 Column Layout

While Grails really makes the MVC portion of web development easier, Cascading Style Sheets (CSS) is still really tough. I wanted a 3 Column layout with a header and footer created using CSS. This sounds easy enough, but it was more difficult than you would think. Especially if you want it to work with multiple browsers.

I spent several hours working on it, more than I would like to admit. Then I ran across Matthew James Talyor's work on 3 column liquid layouts. Matthew did a really nice job and it works exactly as you would expect. So I tried to weave it into a site I was creating. I was using Firefox and everything was going great until I tried to bring it up in Explorer. Ooops!

To make a long store short, I went back to the beginning and scrapped all my pre-existing CSS and started from Matthews. That did the trick. It rendered correctly in Firefox and Explorer both.



I was so happy figured I would probably use this layout again. So, I created a generic Grails application preconfigured to use the 3 column layout. As you would expect, all of the real work is in main.gsp and a new css file I created css file holygrail.css.

So in the spirit of hoping to make someone else's life a little easier, here are the main.gsp and holygrail.css files.

main.gsp


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title><g:layoutTitle default="www.Grails.org"/></title>
<link rel="stylesheet" href="${createLinkTo(dir: 'css',
file: 'holygrail.css')}"/>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
<meta name="description" content="The Holy Grail 3 column Liquid Layout. Pixel widths. Cross-Browser. Equal Height Columns."/>
<meta name="keywords" content="The Holy Grail 3 column Liquid Layout. Pixel widths. Cross-Browser. Equal Height Columns."/>
<meta name="robots" content="index, follow"/>
<link rel="shortcut icon" href="${createLinkTo(dir: 'images', file: 'favicon.ico')}" type="image/x-icon"/>
<g:layoutHead/>
</head>
<body>
<!--
This is a Grails example of the Holy Grail 3 column Liquid Layout work by Mathew Taylor.
For more information, please see his original work at:

http://matthewjamestaylor.com/blog/ultimate-3-column-holy-grail-pixels.htm
-->

<div id="header">
<!-- Header start -->
<g:render template="/common/header"/>
<!-- Header end -->
</div>
<div class="colmask holygrail">
<div class="colmid">
<div class="colleft">
<div class="col1wrap">
<div class="col1">
<!-- Column 1 start -->
<g:layoutBody/>
<!-- Column 1 end -->
</div>
</div>
<div class="col2">
<!-- Column 2 start -->
<g:render template="/common/leftbar"/>
<!-- Column 2 end -->
</div>
<div class="col3">
<!-- Column 3 start -->
<g:render template="/common/rightbar"/>
<!-- Column 3 end -->
</div>
</div>
</div>
</div>
<div id="footer">
<!-- Footer start -->
<g:render template="/common/footer"/>
<!-- Footer end -->
</div>

</body>
</html>



holygrail.css



/* General styles */
body {
margin:0;
padding:0;
border:0; /* This removes the border around the viewport in old versions of IE */
width:100%;
background:#fff;
min-width:600px; /* Minimum width of layout - remove line if not required */
/* The min-width property does not work in old versions of Internet Explorer */
font-size:90%;
}
a {
color:#369;
}
a:hover {
color:#fff;
background:#369;
text-decoration:none;
}
h1, h2, h3 {
margin:.8em 0 .2em 0;
padding:0;
}
p {
margin:.4em 0 .8em 0;
padding:0;
}
img {
margin:10px 0 5px;
}
/* Header styles */
#header {
clear:both;
float:left;
width:100%;
}
#header {
border-bottom:1px solid #000;
}
#header p,
#header h1,
#header h2 {
padding:.4em 15px 0 15px;
margin:0;
}
#header ul {
clear:left;
float:left;
width:100%;
list-style:none;
margin:10px 0 0 0;
padding:0;
}
#header ul li {
display:inline;
list-style:none;
margin:0;
padding:0;
}
#header ul li a {
display:block;
float:left;
margin:0 0 0 1px;
padding:3px 10px;
text-align:center;
background:#eee;
color:#000;
text-decoration:none;
position:relative;
left:15px;
line-height:1.3em;
}
#header ul li a:hover {
background:#369;
color:#fff;
}
#header ul li a.active,
#header ul li a.active:hover {
color:#fff;
background:#000;
font-weight:bold;
}
#header ul li a span {
display:block;
}
/* 'widths' sub menu */
#layoutdims {
clear:both;
background:#eee;
border-top:4px solid #000;
margin:0;
padding:6px 15px !important;
text-align:right;
}
/* column container */
.colmask {
position:relative; /* This fixes the IE7 overflow hidden bug and stops the layout jumping out of place */
clear:both;
float:left;
width:100%; /* width of whole page */
overflow:hidden; /* This chops off any overhanging divs */
}
/* holy grail 3 column settings */
.holygrail {
background:#ff9; /* Right column background colour */
}
.holygrail .colmid {
float:left;
width:200%;
margin-left:-200px; /* Width of right column */
position:relative;
right:100%;
background:#fff; /* Centre column background colour */
}
.holygrail .colleft {
float:left;
width:100%;
margin-left:-50%;
position:relative;
left:400px; /* Left column width + right column width */
background:#FFD8B7; /* Left column background colour */
}
.holygrail .col1wrap {
float:left;
width:50%;
position:relative;
right:200px; /* Width of left column */
padding-bottom:1em; /* Centre column bottom padding. Leave it out if it's zero */
}
.holygrail .col1 {
margin:0 215px; /* Centre column side padding:
Left padding = left column width + centre column left padding width
Right padding = right column width + centre column right padding width */
position:relative;
left:200%;
overflow:hidden;
}
.holygrail .col2 {
float:left;
float:right; /* This overrides the float:left above */
width:170px; /* Width of left column content (left column width minus left and right padding) */
position:relative;
right:15px; /* Width of the left-had side padding on the left column */
}
.holygrail .col3 {
float:left;
float:right; /* This overrides the float:left above */
width:170px; /* Width of right column content (right column width minus left and right padding) */
margin-right:45px; /* Width of right column right-hand padding + left column left and right padding */
position:relative;
left:50%;
}
/* Footer styles */
#footer {
clear:both;
float:left;
width:100%;
text-align: center;
border-top:1px solid #000;
}
#footer p {
padding:10px;
margin:0;
}




11 comments:

Glen S said...

Good stuff. I have fought these battles before too. These days I use YUI Grids for all this stuff (1000 different x-browser layouts in a 4k jar). They even have a GUI Builder for getting the layouts just right. Getting this stuff right is such a hassle, thanks for blogging it up.

dahernan said...

Mee too, with YUI Grids.

Bowenkamp said...

Another great tool to create browser independent layout is YAML Builder from Dirk Jesse.
Dirk developed the YAML CSS- Framework and wrote an excellent book about browser independent layouts.
If you need a special layout, give it a try!

Anonymous said...

It sucks

Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

Reina Sofia said...
This comment has been removed by a blog administrator.
viagra online said...

haha nice I have never try to do this with code almost times I use visual studio, but I need to practice haha thanks for sharing.

viagra price said...

Hello I enjoyed yoiur article. I think you have some good ideas and everytime i learn something new i dont think it will ever stop always new info , Thanks for all of your hard work!.

xl pharmacy said...

Good article!! I got a perfect sensation with this, actually I was thinking on create a blog too, it would be perfect if I take some ideas from here.

sports handicapping services said...

This is an interesting..... great information found here... Thanks very much!

Anonymous said...

Check more about 3 column liquid/fluid layout here