CSS Based Design

Let me tell you why you’re here. You’re here because you know something. What you know you can’t explain but you feel it, that there’s something wrong with the web.

Let me tell you why you’re here. You’re here because you know something. What you know you can’t explain but you feel it, that there’s something wrong with the web. You don’t know what it is but it’s there like a splinter in your mind driving you mad.

You can see it when you look out your browser window or when you turn on your web tv. You can feel it when you go to work, when you go to church, when you pay your taxes.

This is the web that you know. The web as it was at the end of the twentieth century.

This is the web as it exists today…

Welcome To The Desert Of The Web

<table border=0 width=100% cellspacing=0 cellpadding=0>
<td width=100%>
<table width=100% border=0 cellspacing=0 cellpadding=0 vspace=0>
<td valign=bottom><font size=2><br></font>
<table cellpadding="5" cellspacing="0" border="0" width="203" >
<tr><td height="105" valign="top">
<table width=610 cellpadding=0 cellspacing=0 border=0><tr><td width=1><spacer type=block width=1 height=1></td><td width=608 bgcolor=666666 height=1><spacer type=block width=1 height=1></td><td width=1><spacer type=block width=1 height=1></td></tr><tr><td width=1 bgcolor=666666><spacer type=block width=1 height=1></td><td><table width=100% cellpadding=0 cellspacing=0 border=0 bgcolor=e6e6e6><tr><td>
<td width="179" bgcolor="#ffffff" align="left">
<table width="179">
<tr><td><img src="http://pics.ebay.com/aw/pics/x.gif" height="0" width="0"></td></tr>
<tr valign="bottom">
<td valign="bottom" align="left" width="179" height="21">
<table align="left" width="157" cellpadding="0" cellspacing="0" border="0" bgcolor="#ffcc00">
<td align="left" colspan="2"><img src="http://pics.ebay.com/aw/pics/x.gif" width="157" height="2"></td>
<td align="right" rowspan="3" colspan="2"><img src= "http://pics.ebay.com/aw/pics/22x21.gif"
width="22" height="21" border="0"></td>

I didn’t say it would be easy. I just said it would be the truth.

Why Use XHTML?

Web development is a war and we are soldiers, writing hacks and workarounds to make designs look right in buggy older browsers.

What if tomorrow the war could be over? What if we could build sites that won’t fall apart in future browser releases? Isn’t that worth fighting for? Isn’t that worth developing for?

XHTML encourages good practice. All your markup will be well-formed and all your tags will be closed. This makes page rendering easier for browsers and it makes bug-tracking easier for you.

Best of all, using XHTML means that you must keep your presentation separate from your content.

All you have to do is free your mind.

Why Use CSS?

Just imagine all the benefits that come with separating your presentation from your content.

Your pages will be smaller, much smaller. Without the bloat that comes with nested tables, spacer images and font tags, your mark-up will be leaner and meaner. That will appeal to search engines.

Life will be simpler for the people in charge of the design: the presentation of an entire site full of documents can be changed by altering just one file without ever touching the content.

Life will also be simpler for the people in charge of the content: your mark-up will be human readable allowing the content to be updated without changing the rules that govern the presentation.

With Cascading Style Sheets, your content will be accessible to all browsing devices, past and present. That means everything from Lynx to web-enabled mobile devices and fridges.

Remember, all I’m offering is the truth - nothing more.

Where To Begin?

Okay, I’ll try to stop with the Matrix-speak and get down to business.

Where should you start when you want to create a CSS based design?

"Content Is King". It’s a pithy old adage but it’s true.

Everything begins with the content. Everything else is layered on top.

Your finished page will have layers of presentation piled one on top of the other. But if you peel those layers away, what you are left with is the very heart of your page: the content.

Standards compliant browsers will see a beautiful many-layered page. Browsers with partial CSS support will see a partially layered page. Older browsers and search engine robots won’t see the layers of presentation but they will see the page.

The process of adding these layers is called progressive enhancement.

The result of allowing those layers to be stripped away without affecting your content is called graceful degradation.

The first and most important step on the road to CSS based design is having semantically correct mark-up.

That’s just a fancy term for describing your content correctly.

Semantically Correct Mark-up

Put headings and subheadings into <h*> tags, <h1>, <h2>, <h3>, etc.

If a piece of text acts a label for an <input> item in a <form>, then describe it as such by using the <label> tag.

Wrap your paragraphs in <p> tags. If you have a list of links, then put them in a list (<ul> or <ol>) and make each of them a list item, <li>.

You may have pre-conceived notions about how these will look.

The default presentation of tags is a result of browsers following basic rules.

What you must learn is that these rules are no different than the rules of a computer system. Some of them can be bent. Others can be broken.

You think that all <li> list items appear vertically with a bullet point next to them? You think that’s air you’re breathing now?

Free. Your. Mind.

I’m sorry. That was the last Matrix reference: I promise.

<div> and <span>

Sometimes you’ll want to describe some content but there won’t be a suitable tag available. You can’t make up your own tags but you can reach for <div> and <span>.

A <div> is a block level element. That means it’s self-contained and comes with a built-in line break.

A <span> is an inline element. Inline elements don’t include a line break and must be contained within a block level element.

Both <div> and <span> are like blank slates just waiting for styles to be applied to them.

Don’t go overboard with <div> and <span>. If there’s an existing tag that describes your piece of content correctly then use that tag.

Classes and IDs

If you want to apply a style to all instances of a certain tag, then you simply reference that tag in your stylesheet.

If, on the other hand, you want to apply a style selectively, then you’re going to need to add either a class or an ID to the tag.

Classes are reusable. A document can contain any number of tags that use the same class, e.g.:
<p class="myclass">

An ID is unique. A document can only contain one instance of <p id="myid">.

Even though we can name our classes and IDs anything we wish, it’s still a good idea to try to use descriptive rather than visual terms. Describe a class as being "important" rather than "bigredbold".

If we combine the power of <div>s and IDs, we can take the semantic description of our documents even further than the tags provided by XHTML allow.

Most web pages can be divided up into sections like "main navigation", "sub navigation", "main content" "related material", etc.

XHTML doesn’t give us the tags to describe these chunks of content. But if we take the blank slate block-level tag (<div>) and give each section a unique identifier (ID), then we’ve taken semantic description to the next level.

If you mark up your pages with areas like <div id="branding">, <div id="footer">, etc. then you have a way to reference those chunks of content. You will then be able to affect their visual appearance and even change how they are positioned.

Applying Styles

If you’ve followed the advice I’ve given you so far then what you have now is a semantically correct document with no superfluous tags or attributes, broken down into helpful chunks.

Now we can begin to add the layers of presentation. We already have the core.

Inline styles

It’s possible to embed your styles within the very tags themselves e.g.:
<p style="text-align: right;">

But what’s the point of that? We want to separate presentation from content, not mix them up.

The <style> tag

We can give a document its styling instructions from within the <head> tag by wrapping everything up in <style></style> tags.

This is slightly better than inline styles but it still means our content and our presentation are in the same place.

External Stylesheets

By keeping our styles in external documents we achieve a true separation of content and presentation. We can also change the presentation applied to a multitude of documents by altering just one external file.

The easiest way to reference an external stylesheet is by using the <link> tag within the <head> of your document, like this:

<link rel="stylesheet" type="text/css" media="screen" href="path/to/stylesheet.css" />

Notice that there is an attribute called "media" which we have set to "screen". This means that the styles in that stylesheet will only be applied to on-screen presentation. We could use a different stylesheet entirely for printing out our documents, referenced with the "media" attribute set to "print".

The <link> tag is the most universally recognised way of referencing an external stylesheet. Even older browsers with just partial CSS support understand it.

Standards compliant browsers also understand the @import method of referencing stylesheets. We can use this to our advantage. We can provide a basic stylesheet with the simplest of instructions referenced by <link>. We can then add more complex instructions in stylesheets referenced by @import like this:

@import url("path/to/stylesheet.css");

Like the <link> method, we can put our @import command within the <head> of our document (nested in <style></style> tags). However, there’s a much cleverer way of referencing our more complex stylesheets.

We can put our @import command within the basic stylesheet that we referenced using <link>. That means our document only ever references one external stylesheet, a very basic one, but that stylesheet itself references more complex instructions.

Stylesheets within stylesheets. Basic styles for basic browsers. Complex styles for more complex browsers.

Once again, we’ve taken separation to another level. Now our stylesheets have been separated into basic styles and complex styles. We can go even further than this. To make life easier for us, we can have separate stylesheets for typography, positioning, etc., nested like russian dolls, one stylesheet referencing the next.


In our basic stylesheet, the one we reference with <link>, we can put simple information like the basic colours and fonts we want to use.

We start by referencing the <body> tag. Here’s how we specify the font-family we want to be used:

body {
 font-family: "Verdana", "Arial", "Helvetica", sans-serif;

Notice how we can specify different fonts in order of preferences. We want to use Verdana. Failing that, Arial. If Arial isn’t installed, then Helvetica will do. Finally, if none of those fonts are installed, then we say that any sans-serif font will do.


Now we can add some basic colour information. Whenever you specify the colour of something, it’s always a good idea to also specify the background colour.

We could use colour keywords like "white", "black", etc. but they’re fairly limited. We get a wider a range of values by using RGB values like #ffffff, #000000, etc.

Using web-safe RGB values also allows you to use a shorthand method of writing out the values. Instead of writing #6699cc, we can just write #69c.

Here’s how we’d add to our existing styles for the <body> tag to specify black text on a white background:

body {
 font-family: "Verdana", "Arial", "Helvetica", sans-serif;
 color: #000;
 background-color: #fff;


Now that we’ve set the typeface and colour for our document, let’s just take care of our links.

We can style our links to look however we want; bold, italic, underlined, whatever. We can also specify different styles for the various possible link states: link, visited, hover and active. These are called pseudo-classes.

 color: #f93;
 background-color: #fff;
 color: #c93;
 background-color: #fff;
 color: #fc6;
 background-color: #fff;
 color: #f96;
 background-color: #fff;

That’s the right order to specify the pseudo-classes. Here’s a handy mnemonic for remembering the order: LoVe HAte.

Sizes and Units

Whenever we specify the size of something using CSS, we have a number of different options open to us.

When sizing text, for example, we can use percentage values, pixels, points or ems. We can say font-size: 15px, font-size: 120%, font-size: 12pt or font-size: 1.5em. The important thing is that we always specify units of some sort.

Layering The Presentation

Once we have our basic typography and colour laid down and referenced via <link>, we can begin to add more complex styles referenced via @import.

CSS allows us to add typographic flourishes that were previously impossible to achieve on the web. Print designers will tell you how important leading and kerning are when laying out text on a page. The CSS equivalent to leading is line-height. For kerning we use letter-spacing:

.ourclass {
 letter-spacing: 0.5em;
 line-height: 150%;

Another handy feature of CSS is the ability to add a background image to any element.

body {
 background-image: url("path/to/image.file");

We can also control the amount and direction of tiling we want from the background image. This is done using background-repeat. If we don’t want the background image to tile at all, we give this a value of none. If we want it to tile vertically but not horizontally, we give background-repeat a value of repeat-y.

body {
 background-image: url("path/to/image.file");
 background-repeat: repeat-y;

We can also position the background image so it need not necessarily begin in the top left corner of its containing element (the default position for background images). To do this we use background-position and we can specify either keywords, e.g. top, right, etc. or we can use units like pixels or percentages. We can even mix units.

body {
 background-image: url("path/to/image.file");
 background-repeat: repeat-y;
 background-position: 90% 25px;

The Box Model

Every element has an invisible box around it. The content of every element is surrounded by padding. This padding is contained by a border. The border is surrounded by a margin.

The box model: content surrounded by padding, surrounded by border, surrounded by margin

We can manipulate the values of all three of these properties. For instance, we can change the width, style and colour of the border:

 border-width: 2px;
 border-style: dotted;
 border-color: #000;

Or we can combine these all together with this shorthand notation:

 border: 2px dotted #000;

For padding and margin we can specify the width for all four sides. Again, we are free to use any units we want and we can mix units.

If you are wondering whether to increase the padding or the margin of an element in order to add space around it, just remember that the padding extends right up to the border and will inherit values from the element itself such as background-color. The margin on the other hand, begins outside the border and doesn’t inherit values from inside the border.

Here’s one way to specify all four margin values of an element:

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

Or we could use this shorthand notation, going clockwise from the top:

 margin: 20px 10px 20px 10px;

In this case, because the top and bottom values are the same and the the left and right values are the same, we can use even more shorthand and just specify the vertical and horizontal values:

 margin: 20px 10px;

If we wanted the same value on all four sides, all we’d have to declare is:

 margin: 20px;

Many elements have inherent values for margin: it’s what determines between the space between paragraphs or the distance between the edge of the screen and where the <body> begins. We can still manipulate these values. So if you wanted no space between the edge of the screen and the beginning of the <body>, simply declare:

body {
 margin: 0;

You’ve probably noticed that I didn’t specify any units there. Didn’t I say that you should always specify units? Well, there’s one exception to that and that’s when the value you’re giving is zero. Zero pixels is the same as zero percent is the same as zero points.

Adding It All Up

One of the most obvious ways of manipulating an element’s appearance is to change its size. We do this by altering its width and/or height. Once again, we are free to use any units we wish:

 width: 50%;
 height: 100px;

So what happens when we declare an element’s size but we also declare sizes for its padding, border and margin?

 width: 200px
 padding: 10px;
 border: 10px;
 margin: 10px;

In theory, all of these values are added together to give the total width:

 200 (width)
+ 10 (left padding)
+ 10 (right padding)
+ 10 (left border)
+ 10 (right border)
+ 10 (left margin)
+ 10 (right margin)
 260 pixels total width

Unfortunately, the Windows version of Internet Explorer 5 (and, depending on your doctype, IE6) gets it wrong.

Internet Explorer gives the overall total width at 220 pixels. The actual content of the element is reduced to 160 pixels because of the application of padding and border. Only the margin values are correctly applied.

You’ll need to bear this discrepancy in mind when you’re putting together CSS designs but there are workarounds to get around this.


CSS allows us not only to change the appearance of page elements. With block-level elements we can also affect where they appear in the page. This is done using the position declaration together with declarations like top, left, bottom and right.

Again, you can use any units you like, though pixels are probably your safest bet.

By default, all page elements have a position of static which simply means that they appear where they would normally appear anyway, without any CSS trickery applied. When we want to manipulate the position of an element, such as a <div>, then the two most important positioning options available to us are relative and absolute.


Using position: relative, declarations like top and left refer to the element’s normal (static) position in the document:

 position: relative;
 top: 10px;
 left: 10px;

This would put an element ten pixels below and to the right of where it would normally be.


Using position: absolute, declarations like top and left refer to the containing element. In most cases, this would be the <body>:

 position: absolute;
 top: 10px;
 left: 10px;

This would put an element ten pixels below and to the right of the top left corner of the screen.

Once you declare that an element has a position that is absolute, that element is taken out of the flow of the document. Its default position is no longer where it would normally appear. Instead, its default position is the top left corner of its containing element (usually the <body>).

In other words, the order of absolutely positioned elements in the XHTML document no longer matters. Their positions now depend entirely on the CSS. Your document could have <div id="content"> followed by <div id="navigation"> but you could use CSS to place the navigation before the content.

Absolute positioning allows for pixel-perfect designs to be realised although it is more suited to "fixed" rather than "liquid" designs. It also forms the basis of DHTML animation. DHTML is simply the combination of HTML, CSS and Javascript (styles applied to HTML elements can be manipulated with Javascript).


Absolutely positioning elements is all well and good when you know the exact size of each element and the exact position where you want them to appear. It can’t help you if you want the position of one element to depend on the position of another.

You might want to declare, for instance, "whatever follows this element should appear to the right of it". Because absolutely positioned elements are taken out of the document flow, they have no context to relate to.

Luckily, we have the very powerful float declaration which is all about context.

As we have seen, all block-level elements have an in-built line break. A series of block-level elements, such as <div>s appear one underneath the other.

By applying a float declaration of left or right, we can determine what happens to the element that follows. Instead of appearing underneath its preceding element, it butts against it.

For the following examples, let’s assume that each box is a <div> of fixed width and height.

Let’s apply float: left to box number one:

three boxes, two on the first row, one on the second

Box number two butts against the right of box number one.

Now let’s apply float: left to boxes one and two:

three boxes, all in a row

Box number two butts against the right of box number one and box number three butts up to the right of box number two.

We are also provided with an antidote to float. It’s called clear. By applying a clear declaration of left, right or both, we can "break out" of any abutting caused by preceding elements.

Let’s apply clear: left to box number three:

three boxes, two on the first row, one on the second

Even though box number two has a float: left declaration, box number three appears below it instead of butting against it. By declaring clear: left on box number three, we can be sure that nothing will appear to the left of it.

Here’s a fairly complicated arrangement:

three boxes, two on the first row, separated by a gap, with one box on the second row

We’ve declared float: left on box number one so anything following it should butt against its right side. However, it’s followed by box number two which has float: right declared so it appears off to the right hand side. Anything following box number two should butt against its left side. However, in this case the following element, box number three has a clear: both declaration so it doesn’t appear to the left or right of anything.


Putting It All Together

Now you’ve seen just some of the things of which CSS is capable. There are many more stylesheet declarations that I haven’t covered but we’ve seen the most important cornerstones.

  1. Begin with correctly marked up XHTML documents.
  2. Add basic styles with a stylesheet referenced with the <link> tag.
  3. Use @import to reference stylesheets with more complex declarations.
  4. Position page elements either absolutely or relatively.

If you build your websites this way, the rewards will be manifold:

  • Faster loading times: stripping out <font> and <table> tags can bring page sizes down enormously.
  • Backwards compatibility: even the oldest web browser will be able to access your content.
  • Better search engine rankings: Google loves semantically correct documents and hates tag soup. Clever Google.
  • Ease of updates: you’ll be able to update your content without worry of changing your design and you’ll be able to change your design by just changing one or two files.

Welcome… to the real web

Also on AMP

Have you published a response to this? :