FOLLOW USJoomlashack FacebookJoomlashack TwitterJoomlashack Google +Joomlashack RSS

Joomlashack logo blog
Published on 18 May 2007

Joomla Template Tutorial - Using CSS to create a layout

Article Index

Using CSS to create a layout

We will be using CSS to make a 3 column layout for the Joomla template. We will also be making it a fluid layout. There are two main types of web page layout, fixed and fluid, and they both refer to how the width of the page is controlled.

The width of the page is an issue because of the many browser resolutions that people surf the web at. Although the percentage is dropping, about 20% of surfers are using an 800x600 resolution. The majority, 76%, are using 1024x768 and higher (source:www.upsdell.com). Making a fluid layout means that your valuable web page won't be a narrow column in the 1024 resolution, and will all be visible on smaller monitors.

A typical design might use tables to layout the page. They are useful in that you just have to set the width of the columns as percentages, but they have several drawbacks:

  • They have lots of extra code compared to CSS layouts. This leads to longer load times (which surfers don't like) and poorer performance in search engines. The code can roughly double in size, not just with markup but also something called "spacer gifs". Even big companies sometimes fall into the table trap as seen by a recent contorversey about the new disney.co.uk website.
  • They are difficult to maintain. To change something you have to figure out what all the td/tr are doing. With CSS there are just a few lines to inspect.
  • The content cannot be source ordered. Many surfers of the web do not see web pages on a browser. Those viewing with a text browser or screen reader will read the page from the top left corner to the bottom right. This means that they first view everything in the header and left column (for a 3 column layout) before they get the the middle column, the important stuff. A CSS layout on the other hand allows for "source-ordered" content, which means the content can be rearranged in the code/source. Perhaps your most important site visitor is Google, and it uses a screen reader for all intents and purposes.

Let's look at our layout using CSS. You can position elements (stuff) in several ways using CSS. For a quick introduction a good source is Brainjar's CSS Positioning.

If you are new to CSS you might read at least one "beginners guide to CSS". Here are a few suggestions:

Kevin Hale's - An Overview of Current CSS Layout Techniques
htmldog's CSS Beginner's Guide
Mulder's Stylesheets Tutorial
yourhtmlsource.com

We will be using float to position our content. At its most basic, the template might look like this:

<?php defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""
<head>
<meta http-equiv="Content-Type" content="text/html; " />
<?php
if ($my->id) { initEditor(); } ?>
<?php mosShowHead(); ?>
<script type="text/javascript"> </script>
<!--http://www.bluerobot.com/web/css/fouc.asp-->
<link href="/templates//css/template_css.css" rel="stylesheet" type="text/css" media="screen" />
<style type="text/css"> <!--
#wrap {width:80%;}
#header {}
#sidebar {float:left;width:20%;}
#content {float:left;width:60%;}
#sidebar-2 {float:left;width:20%;}
#footer {clear:both;}
--> </style>
</head>

<body>

<div id="wrap">

<div id="header">
<?php echo $mosConfig_sitename; ?> <?php mospathway() ?>
</div>

<div id="sidebar">
<?php mosLoadModules('left');?>
</div>

<div id="content">
<?php mosLoadModules('top');?> <?php mosMainBody(); ?>
</div>

<div id="sidebar-2">
<?php mosLoadModules('right');?>
</div>

<div id="footer">
<?php include_once( $mosConfig_absolute_path .'/includes/footer.php');?>
</div>

</div> <!--end of wrap-->

</body>
</html>

The CSS styles are defined here in the head of the file to show what is going on, but normally they would be in the template_css.css file.

Everything is contained in a box/element called #wrap. This had a width of 80% of the viewport at any time.

CSS Shorthand

Its possible to reduce the amount of CSS by using "shorthand". One example of this is padding and margin styles applied to an element.

margin-top:5px; margin-bottom:5px; margin-left:10px; margin-right:10px;

can be replaced by:

margin: 5px 10px;

There are 'shorthand' styles at the beginning of each style definition. Once you have figured out the styles, fill the shorthand versions in and delete the long versions. The syntax is:

font: font-size |font-style | font-variant | font-weight | line-height | font-family

Here is an example, rather than this...

font-size:1em; font-family:Arial,Helvetica,sans-serif; font-style:italic; font-weight:bold; line-height:1.3em;

Have this:

font:bold 1em/1.3em Arial,Helvetica,sans-serif italic;

Read more at An Introduction to CSS shorthand properties about this syntax.

The left, middle and right columns are each given their own element. Each is floated left and given a percent width that add up to 100%. The clear:both style on the footer tells the browser to "stop floating" and makes the footer stretch across all three columns. This very basic layout would look like this:

[image of 3 column header/footer layout here]

To improve the layout, and to add some breathing room to the content, we need to add some column spacing, commonly called "gutter". Unfortunately, there is a problem here. You might know that Internet Explorer does not interpret CSS correctly. One problem is that calculates width differently. We solve this problem by not using any padding or borders on something that has a width. To get our gutter we add another <div> element inside the columns.

<div id="sidebar">
<div class="inside">
<?php mosLoadModules('left');?>
</div></div>

<div id="content">
<div class="inside">
<?php mosLoadModules('top');?>
<?php mosMainBody(); ?>
</div>
</div>

<div id="sidebar-2">
<div class="inside">

<?php mosLoadModules('right');?>
</div>
</div>

To the CSS we add:

.inside {padding:10px;}

This simple layout is a good one to use for learning about how to use CSS with Joomla. It gives two of the advantages of CSS over table based layouts, it is less code and is easier to maintain. However, it is not source ordered. For that we must use a more advanced layout known as a "nested float". With his kind permission, we will be adapting a layout developed by Dan Cederholm and described in more detail in his book.

Source Ordered Three Column CSS Layout

To help explain how we are doing this, let's look at the end result first.

[PICTURE OF NESTED FLOAT HERE]

The page is split into two main floats. The first, #main-body is floated left, the second, #sidebar-2 is floated right. This is the same as we did before, the #main-body float will appear first in the source code. Now, within main-body, we have two more floats; #content is floated right and #sidebar is floated left. As long as we set our widths correctly, the #content float can appear first in the source code.

<div id="wrap">

<div id="header">
<?php echo $mosConfig_sitename; ?>
<?php mospathway() ?>
</div>

<div id="main-body">


<div id="content">
<div class="inside">
<?php mosLoadModules('top');?>
<?php mosMainBody(); ?>
</div></div>

<div id="sidebar">
<div class="inside">
<?php mosLoadModules('left');?>
</div></div>

<div id="sidebar-2">
<div class="inside">
<?php mosLoadModules('right');?>
</div></div>

</div> <!--end of main-body-->

<div id="footer"> <?php include_once($mosConfig_absolute_path .'/includes/footer.php');?>
</div>

</div> <!--end of wrap-->

So now in the source code we have the order of:

  1. #content
  2. #sidebar
  3. #sidebar-2

To figure out the widths, we now need to do a little math. Let's say we want the side columns to be 25% each. #sidebar-2 is easy, it will just have width:25%. However, #sidebar will need a width defined based on it being within a <div> that has a width of 75%. Its width needs to be 33%.

So, 33% of 75% = 25%

The width of #content will need to be the remainder. We will set it to 66%. The last 1% we split between #content and #sidebar.

The CSS will be:

#wrap {width:80%;}
#header {} #footer {
clear:both;
}
#main-body { float:left; width:75%; } #sidebar-2 { float:right; width:25%; } #content { float:right; width:66.5%; } #sidebar { float:left; width:33.5%; }
.inside {
padding:10px;
}

Some CSS designers would recommend building in a small gutter by making the side columns fractionally smaller. This helps the layout stop from breaking in Internet Exporer. If you wish do do this, simply change the width of #sidebar-2 to 24%

The code of the template is shown below. Its in a scroll box so you can copy and paste into the index.php. Note we have removed the layout CSS from the head. We'll be putting it into a seperate file.

<?php defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""
<head>
<meta http-equiv="Content-Type" content="text/html; " />
<?php
if ($my->id) { initEditor(); } ?>
<?php mosShowHead(); ?>
<script type="text/javascript"> </script>
<!--http://www.bluerobot.com/web/css/fouc.asp-->
<link href="/templates//css/template_css.css" rel="stylesheet" type="text/css" media="screen" />
</head>

<body>

<div id="wrap">

<div id="header">
<?php echo $mosConfig_sitename; ?>
<?php mospathway() ?>
</div>

<div id="main-body">


<div id="content">
<div class="inside">
<?php mosLoadModules('top');?>
<?php mosMainBody(); ?>
</div></div>

<div id="sidebar">
<div class="inside">
<?php mosLoadModules('left');?>
</div></div>

<div id="sidebar-2">
<div class="inside">
<?php mosLoadModules('right');?>
</div></div>

</div> <!--end of main-body-->

<div id="footer"> <?php include_once($mosConfig_absolute_path .'/includes/footer.php');?>
</div>

</div> <!--end of wrap-->

</body> </html>

{mostitle=The Default Joomla CSS}

The Default Joomla CSS

So far all of our CSS has been only about layout. That will make a pretty plain page, so let's add some formatting. We will also move all of the CSS code out of the header of the index.php and into CSS files.

Although it might slow your site down by a tiny amount, it is more flexible to have sub-files for CSS, and then have them all imported by the template_css.css, an example might look like this:

/*Compass Design template CSS file*/

@import url("layout.css"); /*layout css file*/
/* @import url("color.css"); color css file*/
@import url("customize.css"); /*Use this file to customize your website*/

As mentioned earlier, we use @import because Netscape 4 does not understand this command. It also doesn't undertsand CSS, so it will just see our unstyled content as a text browser would.

All of the CSS relating to layout would go in the layout.css file. Once set up you can just leave it and know that any changes you make to other stylesheets won't do anything drastic. The color.css file might contain anything related to color (its commented out as shown here). You can then quickly and easily make changes or set up "color packs". Lastly, all our typography and Joomla styling would go in our customize.css file.

Our layout.css file is now:

/*Compass Design layout.css CSS file*/
body {
text-align:center; /*center hack*/
}
#wrap {
width:80%; /*center hack*/
margin:0 auto; /*center hack*/
text-align:left;
}
#header {
text-align:left;
}
#footer {
clear:both;
}
#main-body {
float:left;
width:75%;
}
#sidebar-2 {
float:right;
width:25%;
overflow:hidden;
margin-left:-3px;

}
#content {
float:right;
width:66.5%;
overflow:hidden;
}
#sidebar {
float:left;
width:33.5%;
overflow:hidden;
}
.inside {
padding:10px;
}

We have centered the page by using a small hack. This has to be done because of Internet Explorer. With standards compliant browser we could just say margin:0 10%; to center the page, but IE does not recognize that. So we center the "text" of the whole page and then align it back left in the columns.

We have also added two more rules. One is overflow:hidden to each column. This will make the page "break" more consistantly as we reduce its width. Secondly we have added a negative margin to sidebar-2. This is purely for Internet Explorer to address some of its issues with CSS. We could apply this rule only to IE by adding a hack (the Tan hack):

* html #sidebar-2 {margin-left:-3px;}

However, hacks are generally troublesome. Its better (in this author's opinion) to apply the rule to all browsers, after all, its just 3 pixels.

At the beginning of the customize.css file we will set some overall styles and have what is known as a "global reset".

/*Compass Design Customize.css file */

* {
margin:0;
paddin:0;
}
h1,h2,h3,h4,h5,h6,p,blockquote,form,label,ul,ol,dl,fieldset,address {
margin: 0.5em 0;
}
li,dd {
margin-left:1em;
}
fieldset {
padding:.5em;
}
body {
font-size:76.1%;
font-family:Verdana, Arial, Helvetica, sans-serif;
line-height:1.3em;
}
#header {
background:#0099FF;
}
#footer {
background:#0099FF;
}
#main-body {
background: #CC0000;
}
#sidebar-2 {
background:#009933;
}
#content {
background: #999999;
}
#sidebar {
background: #009933;
}

Everything is given a zero margin and padding and then all block level elements are given a bottom margin. This helps acheive browser consistancy. You can read more about the global reset at clagnut and left-justified.

The font size is set to 76.1%. The reason for this is to try and get more consistant font sizes across browsers. All font sizes are then set in em. Having line-height:1.3em helps readbility. This means that the pages will be more accessible as the viewer will be able to resize the fonts to their own preference. This is discussed more at:
An experiment in typography at The Noodle Incident (Owen Briggs)

Lastly we have added some background colors so that we can see where the columns are.

With a fresh default installation with Joomla 1.0.8, the template now looks like this:

1st version of blank joomla template

Notice that the side columns do not reach their footer. This is because they only extend as far as their content, where the space is red on the left and white on the right, they don't exist. If we have a template that has a white background for all three columns, this is no problem. We will use this approach and will have boxes round the modules. If equal height columns are desired that are colored, or have boxes, you must use a background image that will tile vertically. This technique is called "Faux Columns" and is described by Douglas Bowman and Eric Meyer.

[TO DO: DESCRIPTION OF FAUX COLUMNS HERE]

Unfortunately, this technique causes a few problems in Internet Explorer. In some situations, the column background will disappear. This is known as the "Peekaboo bug" and is described in more detail at Position Is Everything. It is fixed by applying the Holly Hack (assigning a height of 1% in IE). Here it is slightly modified so that only IE6 is targeted using an !Important statement. This means that no actual hack, i.e. invalid CSS is used.

#wrap{ border:1px solid #999; background: url(../images/threecol-r.gif) repeat-y 75% 0; height:100% !Important;height:1%; }
#wrap-inner { background: url('/../images/threecol-l.gif') repeat-y 25.125% 0; height:100% !Important;height:1%; }

Note at very small screen widths (<600px) in Internet Explorer, the layout will start breaking. Its possible to fix this by hacking a minimum width, but we will leave that as an exercise for the designer.

Joomla Specific CSS

At the time of writing, the current stable of Joomla is the 1.0.X series. This release still uses significant tables to output content in the main body. Along with these tables there are is CSS output available to the designer to style pages. Based on some research by various community members, the current list is shown below. Note it does not include generic web pages styles like H1, H2, p, ul, a, form etc.

#active_menu
#blockrandom
#contact_email_copy
#contact_text
#emailForm
#mod_login_password
#mod_login_remember
#mod_login_username
#poll
#search_ordering
#search_searchword
#searchphraseall
#searchphraseany
#searchphraseexact
#voteid1,#voteid2....
.adminform
.article_seperator
.back_button
.blog
.blog_more
.blogsection
.button
.buttonheading
.category
.clr
.componentheading
.contact_email
.content_rating
.content_vote
.contentdescription
.contentheading
.contentpagetitle
.contentpane
.contentpaneopen   
.contenttoc   
.createdate   
.fase4rdf   
.footer   
.frontpageheader   
.inputbox   
.latestnews   
.mainlevel   
.message   
.modifydate   
.module   
.moduletable   
.mostread   
.newsfeed   
.newsfeeddate
.newsfeedheading
.pagenav
.pagenav_next
.pagenav_prev
.pagenavbar
.pagenavcounter
.pathway
.polls
.pollsborder
.pollstableborder
.readon
.search
.searchintro
.sectionentry1
.sectionentry2
.sectionheader
.sitetitle
.small
.smalldark
.sublevel
.syndicate
.syndicate_text
.text_area
.toclink
.weblinks
.wrapper

Important note about this list.

Many designs you might see actually have given CSS styles that are more specific in their definition. Basically, a more specific rule will over ride a less specific rule.

For example:

a {color:blue;} a:link {color:red;}

.contentheading {color:blue;}
div.contentheading {color:red;}

The color on a link and the color of the .contentheading will be RED, as that rule is more specific (as .contentheading is contained within a <div>)

In the case of Joomla templates, you will often see more specific rules used. This often occurs when the class is on a table. More examples:

.moduletable table.moduletable
  • .moduletable is the name of the <div> that wraps a module. table.moduletable will only apply the style to a table with class="moduletable" on it.
  • .moduletable will apply the style regardless of what element the class is on.
a.contentpagetitle:link .contentpagetitle a:link
  • a.contentpagetitle:link will apply the style to any a tags with a .contentpagetitle class on them that is a link.
  • .contentpagetitle a:link will apply the style to any elements INSIDE .contentpagetitle that are a link.

Specificity is not easy to understand, its often easier to start by using the most general style possible and then getting more specific if the results are not what you expect.

Some links about specificity:
http://www.htmldog.com/guides/cssadvanced/specificity/
http://www.meyerweb.com/eric/css/link-specificity.html
http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

At the moment our template is using alot of tables, 20 in fact! As mentioned earlier, this slows the pages down and makes them harder to update. To reduce the number of tables we need to use $style suffixes in the index.php when we call the modules.

published in Joomla Tutorials

RECENT POSTS