This article is a step by step case study showing you how to transform
your table based web site to liquid CSS based layout. Although the site
we're applying the css layout to is a very specific case.
Liquid CSS Layouts - Design Alternative to Table Based Websites
How to transform fixed table layouts to liquid CSS based layouts
This
article is a step by step case study showing you how to transform your
table based web site to liquid CSS based layout. Although the site
we're applying the css layout to is a very specific case, throughout
the tutorial we will provide various solutions to be applied to your particular case.
Before reading please be aware that in order to fully understand this article you need to:
- Have understanding of CSS (Cascading Style Sheets)
- Have understanding of HTML
- Be familiar to the liquid design concept
- Understand the necessity of cross-browser testing
- Have some basic knowledge of accessibility guidelines
- Have the patience to go through the code and tweak it until the result is satisfactory
Advantages of CSS liquid design over other types of layouts
- Decreases the HTML/body text ratio
- Is completely flexible
- Increases accessibility and usability of a site
- Works well on modern browsers and on some older browsers. Proves to be usable on text-only browsers.
- Looks
as good if not better than table layouts once it's ready. The
misconception that css layouts aren't as visually appealing as standard
layouts has no argumentative base.
Drawbacks of the process
- Requires
a lot of work, time and patience in order to make it compatible with
older browsers and grasp all the details that make a liquid css layout
perfect.
Key principles to CSS layouts
Style sheet layouts are based on the concept of absolute positioning.
That means that every element is perceived as a unique entity that can
be placed wherever on the page in relation to its edges. In this
tutorial we will work with div boxes that act as holders for various elements.
The two most important things to remember are the margins one can set in relation to the edges of the page and the stack order of the div boxes.
The margins of can be set in such a way that a div box can be placed anywhere on the page.
There is an illustration of the concept below. You can easily imagine
how this box could be placed anywhere on the page. It is extremely
useful because while visually they retain the position required by the
design, in the source code, it can be placed anywhere.
The stack order of the div boxes
allow overlapping or preventing it, if necessary, That way you can hide
part of a div box and place something on top instead. Stack order
translates to z-index number. Yes, it's that CSS
command that everyone finds difficult to understand at first contact
with CSS. Below there is an illustration that shows exactly how z-index
works.
You can use your imagination to find countless ways to use the z-index and margin properties. The flexibility of CSS allows virtually any layout to be easily created.
Let's begin
Please bear in mind that all snapshots are in fact thumbnails. You can click on them to see the full image.
Step1 - Analysing the site's original layout
This is how the site in question looked before CSS and liquid design was applied to it. The layout consists in a 1 row 2 column table in which resides the header image and the menu. Below, there is a single column table
in which resides the content. Both tables have 749px in width (hence,
fixed). The screen shot is taken at 1024x768 resolution. The layout
fits perfectly at a 800x600 resolution while at lower resolutions an
horizontal scroll bar is present and part of the layout is compromised.
At resolutions higher than 1024x768 there is a lot of wasted space on
both sides of the table.
Step 2 - Identifying key areas
The layout presents three key areas. The Header image (in green) the Navigation on the top left (in blue) and the Content (in red). We will create a div box for each of these areas.
Variations
Your
website could have a different layout but you should still be able to
identify at least 3 key areas (although not limited to this number).
Write down information related to each of these areas such as:
- Position within the page (margins to the edges of the page)
- Size (width and height)
- Position
relative to other elements (for example where the header is in relation
to the menu. This will help you recreate the layout and keep its
original look and feel.
- Importance (this will help you decide the order of appearance in the source code)
Step 3 - Analysing the source code of the original and final layout
Original layout structure
What
we want is to use CSS to position the 3 areas in the picture above.
Currently the original source code appears as follows (simplified)
<table>
<tr>
<td>Navigation on the top left</td>
<td>Header Image</td>
</tr>
</table>
<table>
<tr>
<td>Content</td>
</tr>
</table>
|
We
have a case of 'what you see is what you get'. Visually the header and
navigation are at the very top while the content is actually below
them. This order is also maintained in the actual source code of the
page.
Effects of the content area being placed at the very end of the source code.
- For
screen reader and other alternate browsers, users on every page they
will 'hear' the header image and navigation being read out before
accessing the actual content. That constitutes a delay in accessing
information.
- All users will have to wait before the header
image, navigation and all other HTML tags (such as tables) load before
reading the content. Studies over the past years show that if users are not presented with content within the first seconds
of the loading of the page, they are inclined to end their visit
prematurely. As a consequence it's important to eliminate any sort of
delay that slows down the process presenting the page.
Final layout structure
The advantage of a CSS layout is that while visually, there will be no change
in the positioning of the three areas (e.g we will still see the
navigation and header being placed at the top and the content below
them), the source code will in fact display as follows (simplified)
<div>
Content
</div>
<div>
Navigation
</div>
<div>
Header image
</div>
|
Advantages of positioning with CSS
- It allows disabled users to hear the content being read out first by their speech-based browser.
- For all users the content will be the very first thing that loads
(the loading time will be virtually instant) leaving the graphics and
other bandwidth consuming elements to load in the background while the
user is accessing the information. While this is a huge advantage for
sites that use many graphics, it is not limited to them. Any site can
reduce load time to a minimum by making use of CSS positioning.
Variations
The
order of div boxes I suggested above is not standard nor should it be
followed to the letter. You can decide which of the key areas is of the
greatest importance for your users and establish the order accordingly.
Step 4 - Let's create the CSS layout
First of all we will create three div boxes corresponding to the three key areas:
<div>
Content
</div>
<div>
Navigation
</div>
<div>
Header image
</div>
|
You can copy the code exactly as it appears above and start from there.
Visually
(and simplified) the output at this point looks like below. We kept
some of the text formatting such as paragraphs, headings and links but
reduced the content. The image below is what corresponds to the
simplified code I provided above.
Not
very appealing is it? The Content area is represented by the text,
followed by the Navigation and Header at last. No absolute positioning
is applied at this point.
While bearing in mind how the site
looked originally let's apply some CSS to each of the three div boxes.
All CSS references will be included in an external style sheet and to
each of the three boxes will be applied a 'class' reference.
In order to be able to position the elements and keep the look and feel of the layout as it was we need some information from the original layout:
Width of the Content area 749px
Width of Navigation area 229px
Width of Header Image 520px
Height of Header Image and Navigation 267px
This information will help us set the right margins for each of the 3 key areas so that they keep their appearance.
The content box. (<div class="content">)
The style sheet reference for the Content box is as follows
div.content {
position: absolute;
margin: 267px 0px 0px 0px;
width: 749px;
z-index: 1;
}
|
position: absolute;
- The box is positioned absolutely to the "edges" of the document. All
margins are set in relation to the top, right, bottom and left of the
page (clock-wise order)
margin: 267px 0px 0px 0px; - The box is positioned 267px from the top and 0px from the other three edges.
width: 749px; - We want the entire Content box to keep its 749px width.
z-index: 1;
- Sets the stack order of the div boxes. The Content box is set to be
positioned underneath any other box with a higher z-index. We will
experiment with that later.
The result
You
can clearly see the Content box (surrounded by thick black border)
overlapping the header. While the Content box is positioned absolutely
(267px from the top), the other two are not (at least not yet).
Important
It is useful to try to ignore all the other div boxes which haven't yet been absolutely positioned. Although they appear
to be positioned in some way they are not. As soon as the first key
area (Content in our case) is positioned absolutely, the following
(Navigation in our case) behaves as if it's the first element in the
source code and positions itself adjacent to the top edge. As soon as
Navigation is absolutely position, the Header area will behave exactly
the same as you see below. As a consequence make an effort to analyse and follow only those div boxes which have already been absolutely positioned. It will simplify things.
The header image box. (<div class="header">)
The style sheet reference for the header box is as follows
div.header {
position: absolute;
margin: 0px;
padding: 0px;
width: 520px;
height: 267px;
z-index: 2;
}
|
position: absolute; - Same as the content box, the Header box will be positioned absolutely.
margin: 0px; - We want the header box to start from the very top and the very left of the screen.
width: 520px; height: 267px; - The width and height of the box should correspond to those of the image.
z-index: 2;
- The stack order is set to prevent a possible overlapping. This way
the image will be 'on top' of the Content box should they overlap.
The result
Still
not much better but let's not give up hope. The header image has got a
thick black border and is overlapping the Content box because of the
stack order we have set.
The navigation box. (<div class="navigation">)
Because
the navigation will be parallel to the header image we need to include
some similar reference to the ones in the Header box
div.navigation {
position: absolute;
margin: 0px;
width: 229px;
height: 267px;
z-index: 3;
}
|
position: absolute; - Again, the box is positioned absolutely
margin: 0px; - We want the navigation box to start from the very top and the very left of the screen.
width: 229px; height: 267px; - Width and height of the navigation box.
z-index: 3; - Because the Header and Navigation boxes will overlap we want the Navigation to be on top.
The result
We've added a bit more text and a background for the Content box and the layout looks like this:
You can see that the Header box is partially overlapped by the Navigation box.
Step 5 - Let's reinclude some of the initial elements
After
positioning the three key areas we want to recreate the look and feel
of the layout as it was initially. We added a background pattern to the
Content box. We also added a div box to the left of the Content box (it
is visually delimited by the darker background). We will call this
Leftbox. You can see how the overlapping of the leftbox and the Content
occurs. This is how the layout looks now.
CSS specs for the Leftbox
We have added this leftbox in order to experiment margins and widths as you will see later.
div.leftbox {
position: absolute;
margin: 267px 0px 0px 0px;
width: 199px;
z-index: 2;
}
|
Variations
In
our layout the navigation starts at the very top but your website might
not reflect that. In fact, a more common layout is where the Navigation
area starts just below the Header image and to the left of the Content
box. If that is the case of your website follow the Leftbox closely as
it is a perfect substitute for it.
The layout is beginning to look appealing. Now we have to fix the content/leftbox overlapping.
We could add an additional left margin of 199px to the Content box in
order to make space for the Leftbox to its left. Unfortunately, later,
when we apply liquid design, Netscape, Opera and Mozilla will not understand the width and margins of the boxes as Internet Explorer does.
We
will aim to making the Content 100% wide but the above mentioned
browsers will add a 199px to that width and produce a horizontal
scrollbar.
A workaround is to push not the Content box but the actual text inside it to the left by 199px.
We have set margins to the text and not the box containing the text.
Additional references have been added in order to achieve the desired
line height, spacing between paragraphs, colour and size.
h1, h2, h3, p {
margin: 10px 35px 25px 255px;
}
|
margin: 10px 35px 25px 255px;
- Because the Leftbox is 199px wide we applied a 255px left margin
(longer than 199px in order to create some space) to all paragraphs and
headings.
Important
If the Leftbox elements are included in paragraphs (<p>) make sure to create a unique reference
for them. Otherwise they will be 'pushed' to the left along with the
paragraphs in the content box and produce a new overlapping.
What we can do is add a special class element for the Leftbox items like below.
p.leftbox {
margin: 0px;
padding: 0px;
} |
What we did was overrule the 255px left-margin specified earlier for the <p> tag.
Not bad! We will fix the Header/Navigation overlapping when applying liquid design. And the source code reads as follows
<div class="content">
Content
</div>
<div class="navigation">
Navigation
</div>
<div class="header">
Header image
</div>
Step 6 - Let's apply liquid design
The only truly fixed element in the layout is the header image. What we will do is create the illusion that it stretches. Take a look at the picture below
The
area selected with a marquee at the extreme right of the image could
very well repeat itself to infinity and you wouldn't even know. We will
crop that area and save it as a separate image called headerbg.jpg.
Variations
This
process differs from case to case. It all depends on the image you work
with. Not all images can create the illusion of repetition.
The
above method will lead to 'expansion' of the layout for higher
resolutions but what about lower resolutions? In our case the picture
is 520px wide (short enough for 640x480 resolutions). Should the image
be wider, at 640x480 a scrollbar will appear and part of layout will be
compromised. A div box can shrink but an image cannot. So what do we do? Read on.
Shrinking an image to fit the resolution
Although
this doesn't apply to our specific case there are workarounds to make
an image 'shrink' and fit to lower resolutions. In order to make the
image appear to be shrinking we will use it as a background of a div box instead of inserting it as a regular image.
This box will thus have the ability to shrink and expand at any time.
Bear in mind a box can shrink, an image can't. When the box shrinks,
part of the image (the one on the right) will be hidden thus avoiding
the appearance of a horizontal scroll bar. See how the image behaves
when the box has shrunken.
In light of what we said above we can say that we need to apply both headerbg.jpg as well as the Header image as backgrounds.
- We need to apply the Header image as a background in order to allow the box to shrink at lower resolutions without compromising the layout
- We need to apply headerbg.jpg as a background in order to allow it to repeat itself when the box expands.
Variations
If
your header image is not wide enough to compromise the layout at lower
resolutions you can simply insert it as normal in the Header div and
only work on expanding the box to achieve liquidity.
Both images are required in order to create the proper liquidity. How do we do that? We know that we can't specify two background images for a single box.
But what we can do is add an additional box to take one of the
backgrounds. Before proceeding we will expand the boxes we have already
created.
Step 7 - Making the existing boxes expand
The easiest way to make boxes expand is replace width: 749px; (for the Content box) and width: 520px;
(for the Header) with width: 100%; The layout will expand as below.
Although the Header box has expanded you can't see the difference
because we haven't yet created the illusion that it stretches.
Step 8 - Creating an additional box for liquidity purposes
Because we will need to apply two backgrounds we have to create an additional box positioned absolutely that will contain all of the other elements. A sort of wrap if you like.
<div class="headerbackground">
<div class="content">
Content
</div>
<div class="navigation">
Navigation
</div>
<div class="header">
Header image
</div>
</div>
|
Think of this box as the lowest layer in a stack of four layers.
Let's
apply a background image to it. We chose to specify headerbg.jpg as a
background image because that's the image we want repeated (for
expansion). We will also add other CSS references such as height: 267px; in order to ensure it as high as the Header box (the fact that it wraps the entire body doesn't) and width:100%; in order to ensure it stretches to a maximum.
div.headerbackground {
background: url("images/headerbg.jpg") repeat-x 0px 0px transparent;
margin: 0px;
height: 267px;
position: absolute;
width: 100%;
z-index: 1;
}
|
At
the same time we place the header image as a background for the Header
box. The way our header image is created requires us to align it to the
left in order to create the desired effect.
div.header {
background: url("images/header.jpg") repeat-x 100% 0% transparent;
}
|
The 100% reference aligns the background of the Header box to the right.
The
headerbackground box will expand as much as the resolution allows it to
and creates the illusion that the header image expands.
Variations
- Should the header image be inserted as a normal picture as opposed to a background the alignment can be made by applying a align="right" to the Header box.
- Instead
of creating a new box (headerbackground in our case) you can use the
body instead for the headerbg.jpg. The drawback is that you won't be
able to set left and right margins as we will in the next step.
body {
background: url("images/headerbg.jpg") repeat-x 0px 0px transparent;
}
Step 9 - Left and right margins and other browsers
Because
we want the layout to breath we want to leave some space to the left
and right. A left and right margin of 4-5% for the body tag sounds
about enough. At this point we can safely say we achieved liquidity in Internet Explorer. The layout expands 100% of what's left after taking out the left and right margins widths. Take a look below:
But what about other browsers?
How do they interpret the 100% width we specified to the
Headerbackground box and the left and right margins? Normally such
references would first apply the left and right margins and then let
the layout expand 100% of what's left. Unfortunately Opera, Mozilla and
Netscape do not see it that way. Take a look below
After some testing we noticed that all three
- Create the left margin properly of 5%
- Add the width of the layout (100%) to it thus making the entire page have 105% in width
- Create an annoying horizontal scroll bar.
Here's a workaround
in order to please the three browsers. We specify a left margin of 5%
for the body tag and replace the 100% width of the Headerbackground box
with 90%. Only the Headerbackground box needs a different width because
the other 3 are wrapped in it. This way the width of the expanding layout will in fact be 95%
leaving an extra 5% as a right margin. This workaround satisfies Opera,
Netscape and Mozilla but slightly shrinks the layout in Internet
Explorer by 5% (although it's not really a tragedy).
Step 10 - Final testing of liquid CSS design
Here are some snapshots taken of the site in its final form. Click to see the whole image.
640x480
800x600
1024x768
Step 11 - Cross browser testing of CSS layout
What we need to do next is ensure that the site looks good on other browsers.
Modern browsers
The site was tested and looks perfectly in Mozilla 1.4, Opera 7.11 and Netscape 7.1 (screenshots taken at 800x600). As you can see there is no annoying horizontal scrollbar.
Older browsers
Out of the older browsers we chose Netscape Navigator 4.75
for testing. Everybody knows Netscape 4.x is a designer's worst
nightmare. In our case the result pretty much fits the profile - a
nightmare. I'm sure many of you have had the same gut feeling when you
opened up your site in Netscape 4. We will work with the present
version of the site that does not have a Headerbackground box nor left
and right margins.
However, we have no right to exclude those using older browsers from accessing the site.
We will work on it until the layout becomes Netscae 4 friendly.
Although the CSS support is very limited we will give it our best shot.
Important
For some reason, Netscape 4's twisted way of displaying CSS does not interfere with and displays the following properly:
- Div boxes margins and paddings
- Stack order (e.g z-index)
These are key to CSS layouts and without them our task would be hopeless.
For the same unknown reason, Netscape 4 does not display properly (all the time or some of the time)
- The float property
- Images in paragraphs
- LI and UL lists margins and paddings
- Whitespace in source code between images
- Background images
These are only some of the oddities of Netscape 4 which we've encountered in our task.
What we will do is let through the CSS references that are supported by Netscape. First of all we will make Netscape ignore the current style sheet completely by using the import command.
|
<style type="text/css" media="all">@import url("style.css");</style> |
Netscape does not support the import command
hence it will ignore any reference in that style sheet. We will link
the document to another style sheet (specially created for NN4) by using
|
<link rel="stylesheet" href="oldstyle.css" type="text/css" /> |
nn4style.css is a modified version of style.css from which we removed references that confuse Netscape 4. We have removed the float property and some of the background-image properties. Netscape will read nn4style.css while modern browsers will read both.
Because the two style sheets are similar, most the references contained
will not come into conflict with each other. Should that happen, the
imported style sheet will overrule the nn4style.css one.
We
have also set some custom negative margins for NN4 in order to achieve
our layout and we also eliminated the whitespace between the navigation
elements.
This is how the layout looks now in Netscae 4.75:
In
text only browsers the main navigation is shifted to the bottom of the
page after the content. While this is an obvious drawback, the page
still proves to be usable. See how the site looks in Lynx.
Although
liquid CSS layouts require a lot of time, effort and above all patience
the benefits are numerous and are certainly worth while.
|