Simple website design using CSS 2.1
April 14, 2010 at 8:05 pm Leave a comment
Today I’d like to address a very simple question: how to rapidly design a website?
The underlying topic we will actually cover concerns the basis of box positioning and floating using CSS 2.1. For those of you who hear a lot about CSS 3, all I can say is that it gives a lot of power to web designers with regards to a website UI and look & feel, but that the CSS 2 box model still rules. It’s important to understand it well.
Again first things first. We need to start with a bit of thinking to actually determine what our website will look like and how it’ll be organized. What I propose that we build together is quite simple: a header, a vertical navigation bar, a main section for the content and a footer at the bottom. In order to structure the website, we’ll use the div element as a generic container for our different sections. divs can be nested, thus once our basic website flow is drafted it’s easy to add as many other boxes as we want (i.e. widgets, content, …) inside our main containers.
Here is what it’ll look like:

Let’s start with the markup structure of the website. As you’ll see it’s quite straightforward. Obviously the div elements will be named according to the sketch above thus don’t hesitate to refer to it.
<!DOCTYPE html> <html> <head> <title>Simple website design using CSS 2.1</title> <style type="text/css"> <!-- CSS rules should be pasted in here --> </style> </head> <body> <div id="pageWrapper"> <div id="header">my header</div> <div id="columnWrapper"> <div id="nav"> <ul> <li>my navigation menu</li> </ul> </div> </div> <!-- end of the columnWrapper div --> <div id="contentWrapper"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </div> <!-- end of the contentWrapper div --> <div id="footer">my footer</div> </div> <!-- end of the pageWrapper div --> </body> </html>
If you display the page as is based on the code above, for sure it will work fine, but it won’t look like the template. In order to make it happen it’s time to work on the CSS rules that will need to be inserted in between the style tags in the head of the HTML file.
I won’t make you wait any longer here is the style part below:
body {
padding: 40px;
}
#pageWrapper {
width: 600px;
margin: 0px auto;
}
#header {
background-color: #ebf2ac;
text-align: center;
}
#columnWrapper {
width: 200px;
float: left;
background-color: #f7cfa7;
}
#nav {
background-color: #ccc;
}
#contentWrapper {
width: 360px;
margin-left: 20px;
padding: 10px;
float: left;
background-color: #dcb9e5;
}
#footer {
clear: both;
background-color: #aaf4ac;
text-align: center;
}
The rule on the body element just gives us some space so that our site isn’t glued to the top left of the browser window.
It all really begins with the pageWrapper rules. As you can see the div is given a width. Since it’ll contain floated div children, I usually prefer to manage the web page layout manually by fixing widths. We could use % instead, but then resizing the browser window can lead to pretty ugly or unexpected results.
The first interesting thing to note is the auto value of the margin shorthand property for the pageWrapper div. The top and bottom margins are set to 0px while the left and right margins are set to auto.
The margin CSS property can take one, two, three or four values depending on whether the box margins are set all at once, in group (top/bottom and left/right for instance with two values as it is the case here) or separately. It’s called a shorthand property because it defines and replaces in one line the margin-top, margin-right, margin-bottom and margin-left CSS individual properties. For more information about the margin syntax please refer to the CSS 2.1 recommendation.
The auto value automatically adapts the left and right margins of the pageWrapper box with regards to its parent: in this case the body element. Concretely it centers our pageWrapper container on the screen. This is a very useful tip and the easiest way to center a box horizontally relatively to its parent container.
The columnWrapper rules are also worth explaining because the div is floated to the left.
By default a block element (i.e. a div) fully occupies the horizontal space it has available from its parent (unless it has a width defined, is floated, is fixed or absolutely positioned for instance). This means that any other following box appears below it.
A floated box however shrinks horizontally to its width (if defined) or to adjust its content width, thus potentially letting space for other boxes to be rendered next to it (on the left or on the right) instead of below it.
By setting the columnWrapper a width and making it float we put it out of the normal content flow (more about this below) and indicate the browser that other floated elements can be rendered on it’s right (since it floats to the left). This is what we do by letting the contentWrapper float as well to the left.
A much simpler way to explain this is each floated box defines a kind of table column and each box content appears only in its own column as one would expect in a table.
There is an useful experiment that you can make to better understand floating boxes. Try and remove the float property from the contentWrapper CSS rules and watch the result: the contentWrapper div now occupies the left side beneath the columnWrapper (as you can see from the contentWrapper div background color). If necessary add some dummy text to the contentWrapper div so it has a great height than the columnWrapper box.
This is what I meant when I said that the columnWrapper wasn’t anymore in the normal content flow when floated. The contentWrapper is positioned as if the columnWrapper doesn’t exist. However the columnWrapper impacts the contentWrapper text that still floats to its right. It is the reason why the contentWrapper div needs as well to declare a float property so that it is rendered properly alongside its left sibling (i.e. columnWrapper).
Also you may have noticed that I set the size of the contentWrapper to 360 pixels while you may have expected 400 (the pageWrapper div is 600px – 200px for the columnWrapper). That’s something to adjust carefully when setting the container dimensions manually. The total width available is actually 400 pixels, but the inner width of the contentWrapper needs to be set to 360 pixels, because it has a margin left of 20px defined and a surrounding padding of 10px which completes the missing 40px (margin left 20px + padding left 10px + padding right 10px).
Since our content will be placed inside either the columnWrapper or the contentWrapper we won’t really have to worry anymore for inner div dimensions within these containers. Again by default inside boxes will adapt to their parent’s dimensions so we only need to set margins, borders and paddings as required, the browser will calculate inner sizes (width and height) of any inside box appropriately.
Float is a difficult topic and needs as well some tweaking on the footer DIV by setting a clear property. Setting clear restores the normal content flow rendering and thus insures that the footer DIV (as a box) is positioned below the highest of the leftColWrapper or contentWrapper DIVs.
Once again you can try to remove the clear property of the footer DIV and watch the result. Did you expect this one? The footer text complies to the float constraint and thus is displayed where it fits along the floated DIVs. The box itself however surrounds the text but actually starts below the last box in the normal content flow i.e. the header DIV.
As I said already float isn’t an easy subject. I suggest you read All About Floats from CSS-Tricks.com for a more complete explanation of how floating elements impact the layout and rendering of a page.
Conclusion: you can see a live example of a similar design on my website. The site itself is still under heavy lifting as I’m recoding everything using CSS3 and jQuery, but it can give you an idea of how to evolve from such a simple design into something a bit more practical.
As usual I’d love to know what you think of this post, whether you find it useful or not? Don’t hesitate to ask questions in the comments or share with us some of your tricks. I’d be curious to know how you do on your own web sites.
Trackback this post | Subscribe to the comments via RSS Feed