Simon Willison’s Weblog

Subscribe

The anatomy of a stylesheet

18th May 2003

To start my series of tutorials, I’m going to go over some of the basics of CSS. This is the boring bit: if you already know the difference between rules, properties and selectors you may want to skip this entry.

The basic building block of a stylesheet is the rule. A rule is a statement applying one or more properties to one or more elements. The declaration of a rule is split in to two parts; the selector and the declaration block, which itself consists of declarations. Each declaration consists of a property and a value. Confused by the terminology yet? Don’t worry, that’s about as complicated as it gets, and I’ll be providing a summary of definitions later on.

Here is an example of a rule:

h1 {
  color: navy;
  border-bottom: 1px solid black;
}

In the above, h1 is the selector; it specifies the parts of the HTML document that the rule should be applied to. In this case, it means "all <h1> elements". The curly braces mark the declaration block, with the two declarations separated by semi-colons. I’ve placed the declarations on different lines but this is purely a coding style thing: CSS ignores whitespace as a general rule.

The meanings of the two declarations should be relatively self evident: color: navy (note the American spelling of “color”) sets the colour of the text to navy blue, while border-bottom: 1px solid black; adds a 1 pixel wide solid black border to the bottom of the element. In fact, this is an example of a shorthand property which allows several properties to be set at once.

There are over 100 properties defined by the CSS2 specification, but they are generally quite straight forward and can be picked up as you go along. Selectors are also straight forward but their importance is often underestimated: in my opinion, understanding them thoroughly is critical to learning to use CSS effectively.

Selectors

The selector part of a rule specifies which parts of the associated document the rule should be applied to. Selectors are always positioned at the start of a rule before the open curly brace. More than one selector can be specified for a single rule, in which case the selectors must be separated by commas:

/* Make all <h1> and <h2> elements navy blue */
h1, h2 {
  color: navy; 
}

The most basic form of selector, demonstrated above, is the element or type selector. It is written as the tag name of an HTML element and matches all elements of that type.

The next most common selectors are those based on classes and IDs. A class is any string of numbers and letters, starting with a letter—for example, “blogentry”, “nav”, “codeSample”, “row2”. Classes can be assigned to any element within an HTML document using the class attribute. Multiple classes can be assigned to an element by placing a list of classes in the class attribute separated by spaces. For example:

<div class="blogentry first">...</div>

The above is the HTML for a div that has both “blogentry” and “first” as classes.

Classes can then be used as part of a selector, by appending a full-stop on to the front of the class name:

/* Colour anything with class="blogentry" navy blue */
.blogentry {
  color: navy;
}

Class selectors can include an element name as well, to limit the application of the rules to specific elements with the specified class:

/* Colour only divs with class="blogentry" navy blue */
div.blogentry {
  color: navy;
}

The above piece of CSS will change the colour of <div class="blogentry">, but will not affect <h3 class="blogentry">.

ID selectors affect elements with a specific id attribute. IDs are like classes in that they can be applied to any element, but unlike classes any specific ID can only be used once within any single document. Classes can be used as many times as you like. As a result, IDs should be used on page items that occur only once, such as a company logo that appears in the top left hand corner of a page. ID selectors consist of the ID with a # sign preprended on to it:

/* Position the element with id="logo" at the top left of the page */
#logo {
  position: absolute;
  top: 0px;
  left: 0px;
}

The above example would position any element with id=“logo” at the top left of the page, using absolute positioning (which I will cover in detail later in the course).

As with class selectors, you can include the element name before the hash sign. This may seem unnecessary since only one item on any page can have a specific ID, but I find doing so helps make the resulting stylesheet more readable as it reminds me what type of element the ID is attached to.

With the basic selectors out of the way, the next most useful selector is the descendant selector. This consists of two or more selectors separated by spaces, and has the effect of matching things that match each of the selectors, going from first to last. For example, div#main a matches all links that occur inside <div id="main">, while div#nav ul.plain li would match all <li>s occuring inside a <ul class="plain"> that itself occurs inside <div id="nav">. Descendant selectors are extremely powerful, and can often be used in place of a large number of class attributes. In general, if you find yourself using a class attribute on every one of a whole bunch of similar elements you may be able to replace them all with a class attribute on a containing element accompanied by a descendant selector in the stylesheet.

Attaching a stylesheet

Now that you know what goes in a stylesheet, you need to know how to attach rules to an HTML document. There are two options: internal stylesheets, where the CSS is included at the top of the page, and external stylesheets, where the stylesheet is a separate file. External stylesheets are generally a better bet as they allow a single stylesheet to be shared across multiple pages (dramatically improving download times as the stylesheet can be downloaded once and then cached by the browser), but I will describe both methods here. Here is the code for an internal stylesheet:

...
<head>
<style type="text/css">
h1 {
  color: blue;
}
...
</style>
...

The CSS rules are placed within a <style> element within the head section of the document. The type="text/css" attribute specifies the stylesheet language being used (on the offchance that another stylesheet language is created some time in the future).

For an external stylesheet, the CSS rules are saved in a file with a .css extension (the file extension is not ompulsory but the file should be served with a text/css content type header, and most web servers are configured to serve .css files using that content type). The HTML to link in an external stylesheet, again placed in the head section, is as follows:

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

That’s all the basic CSS I plan to cover; my next article will start on the core material of the course, which will be a set of case studies showing how existing sites using legacy markup can be dramatically improved through the addition of a little careful CSS.

This is The anatomy of a stylesheet by Simon Willison, posted on 18th May 2003.

Part of series CSS ain't rocket science

  1. Defending Structural Markup - May 4, 2003, 2:20 p.m.
  2. Delay to the start of my CSS tutorial series - May 6, 2003, 2:26 p.m.
  3. The anatomy of a stylesheet - May 18, 2003, 11:56 p.m.
  4. Scripting.com, with added CSS - May 19, 2003, 11:58 p.m.
  5. Defeating IE5 CSS bugs with the help of jwz - May 20, 2003, 11:58 p.m.
  6. Quick tip: Styling blockquotes with CSS - May 21, 2003, 11:54 p.m.
  7. CSS Tutorial: feedback so far - May 23, 2003, 11:59 p.m.
  8. … more

Next: Syntax Highlighting with Javascript

Previous: CSS2 is five years old

Previously hosted at http://simon.incutio.com/archive/2003/05/18/anatomyOfAStylesheet