CSS - the new way to layout

or "How I stopped worrying and learned to love the div"

Introduction

Welcome.

I'm going to walk you through some of the basic steps towards a nifty CSS layout. That means no rows and rows of nested tables with backgrounds, unnecessary attributes, colors, border hacks. This means, ultimately, when you've got it, easy-to-read HTML and a good-looking layout.

If you love your tables, if you don't get this CSS crap, if you hate layouts because they're so complicated, if you hate tables, if you want to get a better grip on CSS or if you've got no idea what constitutes a good layout, you're one of many who would benefit from reading on. I'd do it if I were you.

Let's get started.

What is a good layout?

Perhaps this would be better defined by defining what a good layout isn't.

A good layout

This is all very easy to understand. It all makes perfect sense. You want people to read your text, not look at all the bells and whistles that you can do just for the hell of it. The problem is that around half of all layouts are designed like this.

How many times haven't you seen layouts where 90% of the height or slightly less in width is dedicated to the layout, and consists of useless babble or buttons you can click but won't do anything? Layouts where you have to download five KB of HTML to form a somewhat nice border to the text, or alternatively, the aforementioned babble? Layouts which poke out a hole in the page and place there a tiny box where you have to deal with an extra scrollbar just because the author couldn't deal with making the layout 'stretchable'? Layouts with lime on pink? Layout with text so small, you have to pull out your binoculars, screen reader or screen magnifier? Layout with scrolling text, images or stupid parades? I have, and I'm sick and tired of them.

So from this we can derive:

Tables, a swiss army knife gone bad

Tell me, what can't you do with tables? If you're a table expert like me - actually, I am a recovering table expert, but never mind - you'll say something to the effect of solving world hunger, which evidently you can't do with CSS either, but I digress. The point is that you can do an awful lot of things with tables. Tables is a master of trades. Then why is using them bad? Because tables solves problems it wasn't invented to solve, and CSS often solves them better, easier and in less space.

Let me show you an example of this. Let us say we want a box with a one pixel thick black border, a white background and five pixels of padding. Easy to do in tables, say the table experts. Yes, I say, easy when you know how to do it, but not comprehensible.

Here's the HTML for the table in question.

<table cellpadding="1" cellspacing="0" background="black"><tr><td><table cellpadding="5" background="white" cellspacing="0"><tr><td>Hello. I am the example text.</td></tr></table></td></tr></table>

Not too bad, eh? Actually, yes. Because this snippet is 168 bytes of pure HTML. What if you want to do five of these in your layout? Ten? Fifty? You'll be dealing with an enormous amount of code, even if you just want to say "Hi" in that box.

So what? Do I have a better solution? The table expert is getting a bit mad with me for pointing out problems to his solution. So do I? Actually, yes. Here's how to do it in CSS:

<div style="border: 1px solid black; padding: 5px; background-color: white;">Hello. I am the example text.</div>

This snippet is 83 bytes of HTML and CSS. That is 49.4% of the tables example. The table expert, while largely defeated, now finds the sore spot for this example: it's still 83 bytes. It's not 30 bytes or 10 bytes. It's 83 bytes. But here is where tables end, and CSS truly begins. Watch:

<style> div { border: 1px solid black; padding: 5px; background-color: white; } </style> <div>Hello. I am the example text.</div>

While this snippet was undoubtedly larger, this has one effect that is not visible; on every occurance of <div>...</div>, a box with the properties we've mentioned is created. This narrows our footprint down to an incredible 9 bytes.

I have one more trick up my sleeve. Put this:

<link rel="stylesheet" href="style.css">

...in the header of every html document you want to apply this to, and put

div { border: 1px solid black; padding: 5px; background-color: white; }

...in style.css. Now, on EVERY document where you placed the first snippet, <div>s will go white with a black border. And if you change the CSS in style.css, every <div> will change as well!

This is one of my biggest reasons to love CSS. Next, you're going to learn it.

Styles for newbies

Let me start with this notion. HTML is not code. CSS is not code. Writing any of them isn't programming. This is a central point in getting you to acknowledge this: HTML is different from CSS. CSS is a formatting description language. HTML is a markup language - a language where you mark up your content differently depending on what it is. This is another reason why tables is not nice to use for layouts. <table> and its buddies is made for marking up tabular data, that is to say real tables, with columns and rows. It got widely used for layouts because, simply, there wasn't any other alternatives.

CSS, however, is designed from the ground up to allow you control for formatting, something that we can utilize to create a wide range of layouts and variations. CSS also has an easy syntax. I bet table experts are really tired of going through their code to look for that one cell that made up their border, or to check that the number of <table>s and </table>s are evenly balanced, as to not mess up the rest of the page.

So, now that we mostly know what CSS is designed to do and what it does, let's finally get started on CSS.

An easy CSS rule looks like this:

body { color: green }

What does this do? Change the text color to everything inside <body> green. The body part is called a 'selector'. This is what defines what exactly we should apply the rules to. The rules are everything in between { and }. Every rule consists of a property and a property value. The property is what's before the :; the value of the property is what's between the : and the next rule.

One more example! Let's, in addition to making our text green, change the body text to Arial, 12 points.

body { color: green; font: Arial 12pt; }

We marked the new part this way. Here we see a practical use of multiple rules. The rules are split off by ;.

body { color: green; font: Arial 12pt; }
b { font-size: 14pt; }

We've added a new selector rule. This one turns all bolded text not only bold, but also 14 points big.

All of this we could pretty much do with <table>s or old <font> tags. (You don't have this fine precision with font sizes when using <font>.) Let's show some CSS features.

body { color: green; font: Arial 12pt; }
b { font-size: 14pt; }
p { line-height: 21pt; margin: 0; margin-bottom: 5px; }

Now we're talking. Every paragraph (as marked up with <p> will have a larger line height (the lines won't be as tightly together as they are by default), and will have none of that big space except for five pixels below each paragraph.

body { color: green; font: Arial 12pt; }
b { font-size: 14pt; }
p { line-height: 21pt; margin: 0; margin-bottom: 5px; }
blockquote { border: 1px solid red; }

With this style, the <blockquote> will have a red border on all sides one pixel thick.

Now that you hopefully understand the core of the language and some simple rules, let's move on to harder stuff.

Mo' selecta

In this section I'm going to try to explain a few clever finesses in CSS that allows stricter control over what tags are going to be affected by the rules.

.blah { color: blue; } #bleh { color: red; }

Lots of new stuff! The .blah selector rule will apply every tag with class="blah". The tag-specific rules will still be applies, and you can put multiple classes in the same tag by ways of class="blah bluh", that is, putting a space between them. The #bleh selector rule does the very same, only that while . refers to classes, # refers to id-s, id="bleh". An id is different from a class in three ways. It's an alternate to classes, it should only be used once per documentation according to the HTML specification and in modern browsers, an anchor will be created by using it. If you know of anchors, <div id="moo">Blah!</div> will be identical to <div><a name="moo"></a>Blah!</div> in the linking sense.

a { text-decoration: none; font-weight: bold; } b a { text-decoration: underline; } h1, h2 { font-size: 20pt; }

This shows off the perhaps most used CSS in the world, text-decoration: none, which removes the underline on links. The rest of the a selector rule makes the link bold. The next selector rule, b a, is the first selector in our examples that ties in a little deeper with the structure of the HTML document. This makes every link inside a <b> tag underlined again. You can go even deeper with body p i a, which would apply the rule to a link inside an <i> tag inside a paragraph inside <body>. Our last selector is also pretty useful. h1, h2 applies the rule to both <h1> and <h2>. You can combine the last two, as in b a, a b which would apply the rule to both a link inside <b> as well as a <b> inside a link.

There are a whole lot of more selectors in CSS, but due to space reasons and lack of browsers implementing them (only a few of the latest round of browsers support them) I'm not including those. These mentioned should be enough, and besides, repeating the whole CSS specification is beyond the scope of this document.

In which we get to the layouts

Forget almost everything I've told you before. Don't copy the examples. They will work, but they are of no use if you want to actually create a layout. The purpose of the examples was to teach you a bit of CSS, not teach you how to make a layout with CSS. That's what this section is for. If you're still a bit out in the dark on how CSS works, or you don't know what CSS rule does what, never fear. There are thousands of CSS tutorials that deal specifically with introducing you to a few rules, and explain more in-depth how it works. I'm going to walk you through creating a CSS layout from the beginning. Here's how it works theoretically.

  1. The very first step is to sketch down what your layout is going to look like. On paper or in your graphics software of choice. This is so we'll have something to work against later on. A very good article to read if you want to know more about this creative process is Douglas Bowman's A Design Process Revealed - which coincidentally happens to be about creating a CSS layout.
  2. Once you know how it's going to look, draw any graphics up if needed. Start to design the HTML/CSS and split up images and save as needed.
  3. Test in as many browsers as you have handy. Make sure it looks adequate in as many as possible. No, not everyone uses your browser. Also check in the text browser Lynx. This is so that you can see how it looks in browsers not understanding CSS, or how blind users or Google will 'see' your layout.
  4. Continue tweaking the layout, repeating the previous step as necessary. When you think it looks good enough, upload your images and stylesheets (if needed) and make all your image/stylesheet references absolute - pointing to http://host/address/file, not simply file.

So that's that. That's the basic, theoretical gist of creating layouts. Now I'm going to show you a more concrete example. I'm going to create a CSS layout from scratch.

  1. The first thing I'm going to do is introducing the elementals of a CSS layout. Those can be divided in three parts:

    1. The stylesheet link. Use <link rel="stylesheet" href="url"> to tie your stylesheet in. Everything CSSy we're going to do here, we're going to in the stylesheet.
    2. The identifier element. Use <div class="unique layout identifier"> at the very start and </div> at the very end to confine the spaces. This is done so that your style rules will not interfere with others' layouts. We're using the selector .unique layout identifier just before every selector in the stylesheet.
    3. The rules. The rest, ofcourse, are the stylesheet rules. You can use .unique layout identifier blockquote { display: none; } to hide all quotes in your post, or .unique layout identifier a { font-weight: bold; color: #c00000; } to turn all your links bold and a lovely shade of red in addition to being underlined.

    If you do not have these three in your layout, there's really no point in having one, because it will be terribly crippled.

    So, we're going to start out by laying out the code for a minimum CSS layout.

    <div class="unique layout identifier"><link rel="stylesheet" href="stylesheet url"></div>

    For the rest of this example, we're going to use csstest as our layout identifier, http://example.com/style.css as our stylesheet url, and Shawn for the name of our fictious user.

  2. example layout logoHere's our example layout's only image - the name image. It's 300 pixels wide and 88 pixel high. We're going to use this image in a very neat way in just a minute. So, to resume, here's the whole code:

    <div class="csstest"><link rel="stylesheet" href="http://example.com/style.css"></div>

    Now, I think that looks a bit empty. So I'm going to add in the name:

    <div class="csstest"><link rel="stylesheet" href="http://example.com/style.css"><h3>shawn</h3></div>

    "But that's a header!" you say. "You won't get an image from that!"

    Just watch me:

    .csstest h3 {
       background-image: url(http://example.com/logo.png);
       background-repeat: no-repeat;
       text-indent: -800%;
       overflow: hidden;
       margin: 0;
       height: 88px;
    }

    So what does this do? It indents the text 800% to the left of the <h3>. This means the actual text is moved quite a bit to the left outside of the element. overflow: hidden clips off the box (so that the text is not shown, just 800% to the left of the box - which is what we're actually telling the browser to do) and the two background rules puts in the image in the 88 pixels high box. The practical upshot of all this is that an image is displayed in browsers that support CSS, and that normal text (that inside of <h3>) is shown in browsers that don't. Neat.

  3. Next up, more neatness! We're going to style links. To do this, I enter this:

    .csstest a {
       text-decoration: none;
       border-bottom: 1px dashed #004EC4;
       color: #004EC4;
    }

    This will make all links... I'll leave this as an exercise to the reader. Hint: text-decoration: none; removes the underline.

  4. Almost all CSS layouts nowadays style the quote box, so I'm going to do that.

    .csstest blockquote {
       border: 1px solid #004EC4;
       margin: 0px;
       padding: 5px;
    }

    This is almost freakishly close to our 'box' example earlier on. This will put a blue border on quotes, five pixels of padding all around, and it will not be indented.

  5. And now, some final touches.

    .csstest {
       font-family: Verdana;
       font-size: 0.83em;
       line-height: 1.2em;
       background-color: white;
       color: black;
       padding: 5px;
    }

    Finally, this will set a base font (size a bit smaller than the one used in this document), line height, background, text color and a base padding of 5px from the edges.

Now we have a fully functional, while not absolutely gorgeous, CSS layout. The final code - with

<div class="csstest"><link rel="stylesheet" href="http://example.com/style.css"><h3>shawn</h3>
</div>

as, respectively, header and sig - is light in size and tags, and definitely readable. Compare to an approximative version without CSS:

<table background="white" cellpadding="5" cellspacing="0"><tr><td><img src="http://example.com/logo.png"><br><font size="2" face="Verdana" color="black">
</font></td></tr></table>

This would additionally not give the same font control that CSS has, require changed code for the blockquote to appear similarly, and font tags for the styled links.

To summarize

Learning CSS is definitely worth it. It allows changing your layouts by changing one file and nothing more, more exact type control and some really neat tricks that HTML formatting tags can't compete with. It should be noted that there are table layouts that CSS just can't do, but 99% of those will be doable in the next version of CSS, CSS 3, which will be a valid standard and widely supported in a few years.

I hope you enjoyed this. Now give creating your own CSS layout a shot. It's easy.