Jump to content

HTML CSS Grids based layout (multi-column fluid pages)


Recommended Posts

When working with standards based HTML like HTML 4 or XHTML 1 the goal we all strive for is clean markup that will validate.

A couple of the problems that arise are centering an HTML page, and creating columns for content on the page. The easiest way to achieve columns on a page is to use a table. I'm sure many of us have made a page where a table is used that takes up an entire page. The table has three rows, one for the header, the body, and the footer. The header and footer probably have a [colspan=3] on it so that the body can be split into columns using table cells.

Why is using a table for layouts a problem?

The first question we must ask, in order to answer this question is what element is best suited to the job?

A table element is intended for use in displaying tabular data. They're great for displaying records, and lists, and all sorts of other types of data. Tables are meant to give you an easy way to keep all of that data contained in one block element. What happens if you want to move a column from the left to the right in the table? Each table row has to be edited to reflect the new table layout. Wouldn't it be great to just be able to take the entire column at once and move it from one spot to another? Sorry, but with tables, that just doesn't work. So, tables, by design, are not meant for layout.

This leads us to the second point. Tables aren't all that easy to use for complex layouts, especially when those layouts are subject to change over time.

CSS cascading leads us to another problem. Any style applied to a table is subject to being cascaded down to tables inside of the table. Huh? Suppose we set the font size like this:

<table style="font-size: 90%">

Using % is the way Yahoo recommends setting font size. But if that style is passed from the main layout table down to tables contained within the layout table, your font sizes get progressively smaller. There are other styles that can cause "compounding" problems like that. You should be using relative measurements for font size because that allows folks that resize text on a page to be able to actually resize it. Using pixel measurements for fonts prevents that from working properly and thus site accessibility is reduced for those that can't see the small print.

Nested tables are a big no no in web design. Try to avoid nesting tables as much as you can.

Those are some of the reasons to not use a table for layout.

Well, how else do you layout a page then?

Glad you asked! The HTML Div Element is ideally suited for page layouts. The bad news is that the css rules that are needed to achieve a div based 3 column page, or x column page aren't all that easy to implement.

This is where Yahoo's YUI library comes into play. There are other libraries and css sheets you can use for this. I'm using the YUI library here, feel free to use whatever you're comfortable using. Why use a library? Libraries are useful because folks that are a lot smarter than I have figured out how to achieve layouts that are consistent across the major browsers. These folks also, hopefully, maintain these libraries, updating them when a new browser comes out. Thus, using the library insulates you from changes in the browser market because the library will change and adapt to the new browsers whilst maintaining the most backwards compatibility for you.

Sometimes you might have to update your code a little bit, but not anywhere near as much as you would if you were doing everything on your own.

In order to make use of the YUI Library, we need to include the YUI Grids css sheet on our web page. I've made a page that has the grids css sheet in it. This page has a header, a body, and a footer section. I'm not talking about HTML <head> and <body> tags. I'm talking about a header, body, and footer section inside of the <body> tag. These will be used for out layout.


At this point, you'll see that there isn't much on the page. What we do get for free here though is: our page is centered. All we had to do is add in the YUI reset-fonts-grids.css package and our page will then be centered for us. You might also note that the H3 tags I used did not produce any bold print or bigger font sizes. That is a repercussion of using the reset portion of the css sheet. That is an optional deal and you can opt out of it by just including grids.css. The fonts portion of the css sheet helps to standardize fonts across browsers.


The beginnings of a page layout.


I've added in a div wrapper for the header, body, and footer.


<div id="doc" class="yui-t1"> ....... </div>

There are a number of preset layouts that Yahoo Grids provides. These are set using the id and class on this main div wrapper. This div should wrap all the content on your page. So it starts after the <body> tab and ends before the </body> tag.


That page lists the different presets. id="doc" gives us "750px centered (good for 800x600)" page layout. And the class="yui-t1" gives us "Two columns, narrow on left, 160px". That means the left hand side of the page will have a narrow column of 160px and the other column takes up the rest of the 750px that the id="doc" gives us.

To take advantage of the yui-t1 preset, we have to add some markup to the div with the id "bd" (our body of the page layout).


   <div id="bd">
     <div id="yui-main">
        <div class="yui-b"></div>
     <div class="yui-b"></div>


The yui-main div means that that div will be the main content area (the big column) That div needs to wrap the yui-b div (yui-b means a block, a block where your content goes) that will contain the main content for the page. The second yui-b div will be the narrow column. It should be noted that the second yui-b block can be placed before or after the yui-main div. The order of the markup there does not determine the order that the markup is displayed on the page.


Why is this important?Using a table for left hand navigation puts your navigation before your main content. Google and other search engines might give you a lower page rank because your navigation came before the content on your page that is actually of importance. By having the ability to put your navigation AFTER your main content, you can achieve a higher page rank.

I added in a style for the H3 tag as well. Make sure to view the source so you can see the changes to the script as we go.

At this point, the page doesn't look all that pretty. So the next portion of edits will focus on adding some styles to the page to make it look pretty.


A page with a simple layout.


I've added a few styles to make the page look decent. There's no graphics, but now the header, body, and footer portions of the HTML Body can be clearly seen. There are lots of things that can be done to easily change the layout with minimal changes.

The same page, with a menu on the right hand side


The only change I made was to change the <div id="doc" class="yui-t1"> to <div id="doc" class="yui-t4">.

So one character changes the page entirely. This is the power of YUI Grids.

Want a fluid 100% page width?


The same page with a 100% fluid width.


Now, on this one, there's two changes. <div id="doc" class="yui-t4"> was changed to <div id="doc3" class="yui-t4">.

Because the id "doc" was renamed to "doc3", the css style I applied to #doc has to be renamed as well.


What about diving the main content into columns of it's own?


An excellent question! The way we made the two columns for the body portion of the markup is kinda how we'll achieve this. It is a bit different though since the id="yui-main" can only be used once, at the top level.

Below that, we need to use yui-g for grids, and yui-b for blocks.

The basic pattern for adding two grids is:


<div class="yui-g">
<div class="yui-b first">Col 1</div>
<div class="yui-b">Col 2</div>


You can nest grids, which gives you three (if you only nest one which divides one grid into two grids) or four grids (if you nest a grid into both grids). These can be nested as deep as you wanna go. There are other grid types like yui-gb, yui-gc and so on. Please refer to the YUI Grids page for details about those. It will suffice to say, that you don't always want to split grids 50/50, sometimes you want 25/75 or 33/67. These other grid types allow you to achieve that.

I used the doc4 preset for this last page. And added in a three column "yui-gb" grid which splits the columns into equal portions.


By the way, did I mention the Horizons Game Engine uses Yahoo Grids for it's layout?

Link to comment
Share on other sites

Re: HTML CSS Grids based layout (multi-column fluid pages)

There's one last thing I forgot. Using the Yahoo Grids and the markup associated with it allows for progressive enhancement of a website. By that I mean, if a user access your site and their browser doesn't accept css, the web site will still display in a meaningful way.


This link shows the example page from the last post, with the 974px width centered layout, 160px width left hand menu, and 3 column evenly divided main content area without any css applied to the page.

As you can see, the entire page still shows up in a meaningful way, allowing users of very old browser to still access and use your site. In addition, the simplicity of the markup makes the website a lot more accessible with screen readers and whatnot.

Link to comment
Share on other sites

Re: HTML CSS Grids based layout (Add a dynamic menu)

To continue the example, why not take the left hand vertical menu and add some affects to it.

Here's a link to the file:


The first thing we need to do is remove the old styling on the left hand menu.

I deleted this:

	.side_bar {
	background-color: #001873;

.side_bar div{
	background-color: #001873;
	padding: 4px;


Then we'll change the menu's HTML markup a bit, like so:

<div id="side_bar_menu">
<div class="bd">
<h6>Menu Navi</h6>
[*][url="#1"]Link 1[/url]
[*][url="#2"]Link 2[/url]
[*][url="#3"]Link 3[/url]
[*][url="#4"]Link 4[/url]
[*][url="#5"]Link 5[/url]
[*][url="#6"]Link 6[/url]
[*][url="#7"]Link 7[/url]
[*][url="#8"]Link 8[/url]


Note that I moved the Menu's header to a H6 tag, and put it inside the two divs that contain the menu. The outer div is the main container. The id attached to that div is what the javascript menu constructor will use to make the menu. The inner div is what will be the menu. It gets a class of "bd" because it's the "body" of the menu.

We'll need to add in some javascript include files. We're using the YUI Menu widget, so we need this:

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/menu/assets/skins/sam/menu.css"> 

<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/container/container_core-min.js&2.6.0/build/menu/menu-min.js"></script> 


The HTML Body element gets a class applied to it which is used by YUI to provide a default presentation for YUI widgets.

<body class="yui-skin-sam">


Just before the closing </body> tag, we'll add in a <script> tag that will link the javascript file I'm using to construct the menu.

<script type="text/javascript" src="layout.js"></script>



The javascript code only takes two lines for us to get a menu.

myMenu = new Menu('side_bar_menu', {position: 'static'});


I've wrapped my code in an anonymous self calling function and created an alias for the YAHOO.widget.Menu constructor. (Menu)

The rest of the html file stays the same as it was in the last example (with css).


Well, that menu doesn't look very good :(


I took the last file and added some css to override the default YUI skin. And now the menu looks like it did before, but now it has some nifty hover over affects.


All that has been added are css styles in the HTML Head of the document.


Okay, but that was a lot of work just to get some hover affects...


However we've also gained the ability to have fly out menus. Adding an unordered list to one of the LI's in the menu, and wrapping that new list with a container div (doesn't need any classes or id's) and then a second div (needs a class of "bd") will give you a fly out menu. This process can be repeated as many times as you like giving you as many submenus as you like.

And here's the menu, with three sub menus, and one sub sub menu.



And now you've got a fantastic set of menus that not only give users using css capable browsers an optimal experience, but users who's browsers don't accept css will still be able to access your navigation system because the HTML Markup is all semantically correct.

Here's the file without any css and without the javascript menu constructor:


Link to comment
Share on other sites

  • 5 months later...

Re: HTML CSS Grids based layout (multi-column fluid pages)

prolly this is the best place to ask for help as it goes into the subject.

I have a 3 column, header and footer layout. though how can i make the left and right columns height, meet the footer, taking that "content" div is bigger than both left and right ones?

Link to comment
Share on other sites

Re: HTML CSS Grids based layout (multi-column fluid pages)


prolly this is the best place to ask for help as it goes into the subject.

I have a 3 column, header and footer layout. though how can i make the left and right columns height, meet the footer, taking that "content" div is bigger than both left and right ones?

Try a container div, float the 3 inner divs correctly and set the container div with a background and it will make the illusion that it has a background.

Link to comment
Share on other sites

Re: HTML CSS Grids based layout (multi-column fluid pages)


Try a container div, float the 3 inner divs correctly and set the container div with a background and it will make the illusion that it has a background.

Had tried that at first but even with the container div there's not much use :(

And after Floydian's reply, i went digging some info, and it seems the solution goes in fact by using some javascript to make the work around :|

Link to comment
Share on other sites

Re: HTML CSS Grids based layout (multi-column fluid pages)

I've used the javascript deal to do this on http://www.phphorizons.com/

On any page on that site, viewing the source, and scrolling down a ways, and you'll see this js script:


<script type="text/javascript">
(function () {
var Dom = YAHOO.util.Dom,
Region = YAHOO.util.Region,
Lang = YAHOO.lang,

secondMenu = new YAHOO.widget.Menu('secondMenu', {
	position: 'static'

testOutPut = Dom.get('testOutPut');
sideBar = Dom.get('sideBar');
bdBlock = Dom.get('bd');
sideBarRegion = Region.getRegion(sideBar);
bdBlockRegion = Region.getRegion(bdBlock);

if (bdBlockRegion.bottom > sideBarRegion.bottom) {
	newHeight = bdBlockRegion.bottom - sideBarRegion.top;
	sideBar.style.height = newHeight + 'px';

//	testOutPut.innerHTML = Lang.dump(bdBlockRegion);




It does use Yahoo UI though.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...