Basic Introduction to CSS

This page is intended to give a broad introduction into designing websites using CSS (Cascading Style Sheets) and is aimed at people who are not currently using this technique. It is not intended to be a comprehensive manual (there are lots of good books and websites for that) but is rather aimed at convincing designers who may arrive here that this is the way to be doing things.

CSS offer the most up-to-date, flexible and correct way to design web pages.

By correct I mean that CSS websites, when properly implemented, are most usable in terms of compatability with disability and accessibility software (e.g. screen readers for the blind), allow end users to adjust fonts to suit their eyesight, have a logical document flow and so on. Flash and tables based layout, on the other hand, are not correct ways to design a website.

Please note that if you’re using an old browser then you may not be able to see all of the CSS examples, indeed, this whole site may not be displaying correctly! There’s rarely an excuse to be using an out of date browser, if you are then go download Opera or Firefox now.

Seperating Style From Content

The main principle behind designing web pages using CSS is the separation of style from content. This isn’t a concept that stands out as immediately obvious, but once you grasp the idea you’ll wonder why you ever wrote websites in any other way!

Basically, your XHTML should only describe what the data is, whilst the CSS should define how it looks. So the XHTML doesn’t say ‘put a big red box in the middle of the page with the word WARNING inside’, it only says ‘here is a box containing the word WARNING’. It is the CSS that defines the box as big and red and dictates its location.

The art of creating XHTML in this way is known as writing semantic markup, and it is from this practise that the flexiblilty of CSS is drawn. Using semantic markup also avoids ‘tag soup’, meaning that the resultant XHTML document is very clean and easy to read and edit since it contains only data and no presentational information.

To explain this principal, let’s imagine that we’re creating a web page without the use of CSS and we decide that we want to jazz up our header a little. We would have to use something similar to this:

<font color="red" size="120%"><u>Welcome to Neverland</u><font>

When designing with CSS we would never use that sort of markup. Firstly let’s imagine that we want to duplicate that style further down the page; maybe we have another title that we want to print. We would end up typing out that whole font tag again! That’s a big waste of time, what would be better is to define how we want titles to look, and then when we want a title we simply call upon the pre-defined style.

This is essentially what CSS allows us to do (on a basic level):

.myHeading
{
   color           : red;
   font-size       : 120%;
   text-decoration : underline;
}

And then in our XHTML we may have something along the lines of:

<p class="myHeading">Welcome to Neverland</p>

Already, we can use that style as many times as we like because it’s defined and ready for us to use. Now, and here’s the crux of the thing, if we decide we want to change the way our headers look we only have to change the style definition and every heading on the page will change automatically. This ensures consistency throughout the page.

However, if we make the style sheet a separate file, we can change the way the entire website looks by only changing a couple of lines. Now do you see the power of the tool? It doesn’t matter whether we have a ten page website or a ten thousand page website, by using CSS for the design the entire site can be altered in seconds.

Here we have seen an example of creating a class, something that we define and re-use to our own ends. Using CSS though we can also take control over the appearance of all of the default HTML elements, such as paragraphs, headings, the body, links, lists and so on in order to make our site appear exactly as we wish.

Where Does the CSS Live?

There are three places that you can place style information:

In-line

You can place style information within an element itself (referred to as in-line). This is only useful if you know for sure that you’re never going to need to use that style anywhere else. So, let’s say you’re running some sort of an adult venture and you want a big warning box on the front page that’s not going to appear anywhere else:

<p style="font-size: 200%; padding: 10px; border: 5px solid red;">WARNING!</p>

Would result in the following:

WARNING!

Headers

You can also place style information within the heading of a web page. This is used if you want the same style to appear several times within a single document, but not in more than one document on your website:

<head>
   <title>Page Title</title>
   <style type="text/css">
      .warning
      {
         font-size : 200%;
         padding   : 10px;
         border    : 5px solid red;
      }
   </style>
</head>

CSS files

Finally, and this is the most useful and common application, you can place your style information into a separate file and link to this file from within your header. Obviously, the same style sheet can be linked to from many different pages. In this case, mystylefile.css is in the same directory as our web page, and would just contain lines 4-9 from the above text:

<head>
   <title>Page Title</title>
   <link rel="stylesheet" type="text/css" href="./mystylefile.css" />
</head>

What’s Cascading About It?

The key thing about CSS is that is does what it says on the tin, cascades!

Firstly this means you don’t have to specify all of the mark-up for each element in one place. When the page is rendered all the CSS is interpreted and each part of the page will have a cumulative style applied to it.

For example, if our style sheet contains the following:

body  { font-size   : 120%; }
#main { font-weight : bold; }

If we have a div called #main, with some text inside, the text will be both bold and also 120% size of the browser default. This is because all the text in main falls into both the categories of being part of the body and also within #main.

Secondly elements may be defined in the CSS more than once either accidentally or on purpose by yourself. These conflicts are resolved using a hierarchy of specificty.

Essentially the more specific definition wins. So, say you have a style sheet for your whole site which defines a font for the body, but then you stick some new CSS in one of your page headers which re-defines the body font, then that page will use the font from the header because this is less generalised, i.e. more specific. Similarly, an in-line definition would be used in preference to style information in the page header.

Sometimes is is necessary to cheat and force a re-definition to be used by adding the !important suffix to a CSS rule, but this is not universally supported.

Defining Scope

There are different ways to define scope within CSS, meaning exactly which elements will be affected by a rule.

Basic Elements

The most simple example, giving the broadest scope, is to alter all instances of a basic HTML element. For example, we could make all instances of h1 also bold, using:

h1 { font-weight: bold; }

This will affect any h1 elements, no matter where they come within the document.

Classes

You can define a class, and then this class can be applied to different types of elements. For example, we can define a class blueBackground, and this could be applied to any elements which we want to have a blue background.

The class is defined with the syntax .className, as follows:

.blueBackground { background: blue; }

and then we apply it within the HTML as follows (note that if you wish you can apply mutiple classes to an element):

<p class="blueBackground">this has a blue background</p>

Of course, blueBackground is not a semantically correct name for a class, did you spot that?

Imagine if we used this class a thousand times and then decided that actually everything with a blue background should be red, the class name would no longer make sense. In reality remember to only use semantic names (names that descibe what the data is, not how it looks) such as filmReview, comment, shoppingList and so forth, not thisIsRed, boldText, style1 etc.

The notation .className means apply this formatting to any element given this class. You can also use the notation element.className in order to define markup which will only apply to elements element given the class className.

For example, if we define the following styles:

  .blueBackground { background  : blue; }
h1.blueBackground { font-weight : bold; }

And then use them as follows:

<span class="blueBackground">this has a blue background</span>

<h1 class="blueBackground">this has a blue background and is also bold</h1>

IDs

An ID is unique, and is given to a single element within the page. If you re-use an ID the page becomes invalid, and remember, validation is fun and important!

For example, if you have a menu and you want to do something special to the currently selected item, you may give it an id called ‘selected’. If you break your page down into divs for layout then you’ll likely give each div its own ID as well, as follows:

<div id="banner">
   Here is my banner text, corporate logo or whatever.
</div>

We can then define the properties for the banner using the #ID notation, as follows:

#banner { border: 1px solid black; }

Sub selections

You can specify a sub selection which is an element appearing within a parent element e.g. to set the padding of all p elements within the ID #main:

#main p { padding: 10px; }

Pseudo-selectors and pseudo-classes

Some elements have so called pseudo-selectors, which are special instances or parts to an element. These are pre-defined within the CSS specifications, you can’t make up your own.

The syntax that is used is element:pseudo-selector.

For example, the link tag has three psuedo-elements, being a:visited, a:active and a:hover. The a:hover item is incredibly useful, and is used an awful lot for doing fancy things with menus.

For example if we write the code:

a       { text-decoration: none;      }
a:hover { text-decoration: underline; }

We can create an effect where by our links are only underlined when we roll over them with the mouse.

Lists

You can specify a simple comma delimited list of any of the above, and apply style to all things in the list:

h1, b, a, #main p { font-size: 130%; }

Units

There are various different units that you can use to specify sizes in your CSS. I’m not going to go into a lot of detail here but suffice to say you need to be aware of the correct units to use in each instance.

For example, the px (pixels) unit is static, so whilst a box of 800px width will fill a users screen at 800x600 resolution, it will be teeny on a 1400x1050 resolution screen. For this reason, careful use of % and em (the area taken up by a single ‘M’) are often better options as they will scale in size with different resolutions, if that is the effect that’s desired.

The CSS Box Model

When applying style using CSS, it helps immensely to bear in mind the ‘box model’. This is defined by the W3C here.

The box model allows us to consistenly imagine elements within a box, and we can control various aspects of the box such as its background, border and spacing from neighbouring boxes.

The boxes nest within eachother just as the elements nest within each other, so for example all boxes are within the body box. Even when a website appears to have a curved, rounded or flowing effect is it still achieved in some way using boxes as boxes are the only way in which a page is rendered.

Here are some of the things that the box model allows us to control:

Border

The border is just that, a border around the element. In the same way as the padding and margin explained below, you can apply an entire border or any number of the component parts (top, bottom, left and right).

For example:

<p style="border: 1px dashed green;">
   a bordered paragraph
</p>

<p style="border-right: 1px solid red; border-top: 1px solid red;">
   a partially bordered paragraph
</p>

Gives:

a bordered paragraph

a partially bordered paragraph

You’ll note that I changed the border style there, you can choose from solid, dotted or dashed.

Padding

You’ll notice in those two examples above that the text is squished right up to the border. What we may want to do is increase the padding, which is the space between the border and the content of the element:

<p style="border: 1px dashed green; padding: 10px">
   a bordered paragraph with 10 pixels padding
</p>

Gives:

a bordered paragraph with 10 pixels padding

Recall you can set all round padding, or control padding-left, padding-top etc.

Margin

The margin can be thought of as the outer padding, and is the space between the border and whatever’s next to the element. So, let’s say we have a couple of divs with no margins set:

<div style="border: 1px solid green;">
   div number 1
</div>

<div style="border: 1px solid blue;">
   div number 2
</div>

These render like this:

div number 1
div number 2

If we do not want them squashed together we can add a bottom margin to the first div:

<div style="border: 1px solid green; margin-bottom: 1em;">
   div number 1
</div>

<div style="border: 1px solid blue;">
   div number 2
</div>

Giving:

div number 1
div number 2

Background

You can set the background to various different things:

  1. Transparent (default)

    If the background is set to transparent (or not specified), the background from the element below will show through. If there’s no element below then the background from the body will show though. For example:

    <div style="background: red;">
       outer div
       <div style="background: transparent;">
          inner div
       </div>
    </div>

    Gives us:

    outer div
    inner div
  2. Solid

    You can set a solid background colour using standard HTML techniques, so red, #FF0000 and #f00 are identical. For example:

    <div style="background: red;">
       outer div
       <div style="background: yellow;">
          inner div
       </div>
    </div>

    Gives us:

    outer div
    inner div
  3. Image

    The ability to set background images with CSS is one of the most powerful features that we can use. Indeed, it allows us to define the whole look and feel of a site from within one file, including backgrounds for the body, banners, footers, headers and so on.

    You can set the background to be an image, using the following syntax:

    p { background: white url(image.jpg); }

    This will use image.jpg as the background for the p, and if there is any area in which the image is not displayed (if it is being displayed only once and the paragraph grows beyond the image size) then the colour white will be substituted.

    CSS gives us more control over our background images though, such as repeating only on a single axis, or keeping the image static (i.e. not scrolling when the page scrolls).

    For example, to set image.jpg as the body background, centred in the middle of the page with no scrolling:

    body
    {
       background-image      : url(image.jpg);
       background-repeat     : no-repeat;
       background-attachment : fixed;
       background-position   : center center;
    }

    You can look here for more information on image backgrounds.

CSS for Print and Media

Say you decide to print this page and keep it for reference; the problem is going to be that you’re going to get the banner at the top, which you don’t want, and menues at the side, which you also don’t want. The menus will cause the entire text body to indent, which is a waste of paper and so on—this is where CSS saves us! What we do is specify a second style sheet, one that we’re going to use for print.

So, our header might look something like this:

<head>
   <link rel="stylesheet" type="text/css" href="sheet.css" media="screen" />
   <link rel="stylesheet" type="text/css" href="sheet_print.css" media="print" />
</head>

In there, sheet.css is our normal style sheet, sheet_print.css is the one we want to use for printing. When we print the page, the style sheet speicifed for the print media will be called, when we request the page with our browser, the style sheet speicifed for the screen media will be called.

This lets us make something appear differently when it’s printed that when it’s displayed on screen, and eliminates the need for ‘printer friendly version’ links.

Firstly, any divs that you don’t want, you just clear away using the display attribute as follows:

#banner, #sidebar
{
   display: none;
}

Then you can set about making your type nice and legible for print, something along the lines of:

body
{
   color      : black;
   background : white;
   font       : 12px/1.2 Verdana, Arial, Helvetica, sans-serif;
}

There is a lengthier article about this here.

There are other medias as well that you can specify sheet for, such as tv or handheld, which are specified here

CSS for Layout

Pretty much all of the above information has related to styling things using CSS, in one way or another. I have left layout using CSS until the very last, because it’s the most difficult part and contains a lot of trial and error.

Historically a page layout was achieved using tables—tables should no longer be used for markup! Remember that we are trying to create semantically correct pages, so tables are only used for tabular data and nothing more.

So why is using tables for layout so wrong? Well, firstly there are the computational and legibility issues. As the layout becomes more complex, so do the tables, until the code is just a huge mass of td and tr tags and you can’t see where any of the content is. This is bad for anyone trying to edit the site and work out what’s going on, and also introduces a lot of overhead while the browser tries to make sense of the giant nested tables.

Secondly, using tables for layout makes for a completely rigid design with no flexibility. Imagine if you had a table based site and wanted to move the menu from the left to the right. How long would it take you to move the menu over to the other side of the page on a couple of hundred pages?

With CSS, By breaking our page down into logical divs (for example a banner div, a menu div and a content div), and then specifying the position of each div within our style sheet, we can change the page layout simply by altering the style sheet.

The problem is, how do you lay out a site using only CSS? To be honest, it’s hard. It takes a good understanding of the box model and how to float elements. There are various ‘layout reservoirs’ sich as Glish which offer good starting points, and I would suggest that you have a look at these and make sure that you understand them before attempting your own layout.

It seems only fair that we run through an example here though! This is the general process that I use which I have arrived at over several years.

Once you are ready to create your own design, draw it out on paper using boxes for each content area. Remember that every element is contained within a box; this doesn’t necessarily mean that the box has a border but it sits within a box none the less.

This doesn’t mean that the site will end up looking ‘boxy’, the design will look however you wish later on via the use of background imagery and colours. For example I layed out this site for a collegue using CSS which is graphically quite advanced. You should also check out the CSS Zen Garden if you are in any doubt as to how diverse and beautiful CSS based sites can be.

If you can create a structure where none of the boxes overlap, your life is going to be easier. If you can’t, then you’re going to have to learn about absolute positioning and so forth. Do not be afraid to use additional wrapper divs in order to group divs together, but do try to avoid redundant containers.

You should start by drawing out the broadest arrangement of boxes, so if you have a few menus under one another, just draw one box for the menu and worry about the individual menus later on.

Your challenge then is to re-create the structure on screen using all of the techniques that CSS allows. Create a basic XHTML document and enter divs for each section you have on paper, with the name of the div inside.

Enter them into the file in the order that you read down your paper layout, top to bottom and left to right. You will find it useful to put all of these elements inside a ‘wrapper’ div which will let you set the overall size of your content easily if required.

<!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" xml:lang="en" lang="en">

<head>
   <link rel="stylesheet" type="text/css" href="/style.css" />
   <title>New Layout</title>
</head>

<body>
   <div id="wrapper">
      <div id="banner">
         banner
      </div>
      <div id="menu">
         menu
      </div>
      <div id="main">
         main content
      </div>
      <div id="footer">
         footer
      </div>
   </div>
</body>
</html>

You can then enter all of the divs into your CSS file, setting a different coloured border for each one.

#wrapper
{
   border: 1px solid black;
}

#banner
{
   border: 1px solid red;
}

#menu
{
   border: 1px solid lime;
}

#main
{
   border: 1px solid green;
}

#footer
{
   border: 1px solid blue;
}

You should now have something like the following if you view your page:

You then need to make the layout match the paper layout by adjusting the width, height, padding, margins, floats, clearing and position for each div, which is the hard bit!

Only a good understanding of the box model, lots of reading and some patience can help you there; I can not cover every eventuality here. You should bear in mind certainly how the box model is calculated, how padding and borders affect the overall width of elements on screen and so on.

Here’s an example for the simple layout that I’ve sketched above for a full screen layout, as basic as it can be with very little tweaking:

#wrapper
{
   width : 100%;
}

#banner
{
   border: 1px solid red;
   width : 100%;
   height: 50px;
   margin: 0 0 2em 0;
}

#menu
{
   border: 1px solid lime;
   float : left;
   width : 25%;
   margin: 0;
}

#main
{
   border: 1px solid green;
   float : right;
   margin: 0;
   width : 70%;
}

#footer
{
   border: 1px solid blue;
   width : 100%;
   float : left;
   clear : both;
   margin: 2em 0 0 0;
}

We size the banner, and then float the menu left and the main content right. We then clear these floats and have the footer at the bottom. As you can see, this small amount of CSS has caused the divs to jump to roughly where we need them (I have added a bit of filler text to make it easier to see):

If we decide that we want a fixed width page, we can have that also by using our wrapper div.

Fixed width pages can be easier to read if you have a lot of text as you have some control over the line length; you should consider what is best for your site. It is certainly fair to say though that you have greater control over a fixed width site and it makes it easier to create custom graphics and not worry about tiling.

Let’s constrain our layout to 780px so that it displays on an 800x600 screen, and space out the areas with some padding and margins:

#wrapper
{
   position : absolute;
   border   : 1px solid black;
   width    : 780px;
   right    : auto;
   left     : 50%;
   margin   : 0 0 0 -390px;
}

#banner
{
   border   : 1px solid red;
   width    : 740px;
   height   : 50px;
   padding  : 10px;
   margin   : 10px 10px 0 10px;
}

#menu
{
   border   : 1px solid lime;
   float    : left;
   width    : 200px;
   padding  : 10px;
   margin   : 10px;
}

#main
{
   border   : 1px solid green;
   float    : right;
   width    : 506px;
   padding  : 10px;
   margin   : 10px 10px 10px 0;
}

#footer
{
   border   : 1px solid blue;
   float    : left;
   clear    : both;
   width    : 740px;
   padding  : 10px;
   margin   : 0 10px 10px 10px;
}

And here we can see that this has given us a nice, magazine style fixed with layout:

Of course, neither of these sites look very exciting yet, but the layout is the hard bit. Once the layout is sorted it’s very easier to start adding colour, graphics and typography to bring the site to life.