Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

The anatomy of a stylesheet

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.

Tagged ,

View blog reactions

Next: Syntax Highlighting with Javascript

Previous: CSS2 is five years old

16 comments

  1. Nice to see that you've finally got round to this... I'm sure it will be greatly appreciated by many! Just a little thing - is it worth giving it a category of it's own? Like "tutorial" or something? Might just make it easier for the rest of us in the long run. I know you've got your search and all, but it's just a thought.

    This is the boring bit: if you already know the difference between rules, properties and selectors you may want to skip this entry.

    I still read it! And only one spelling mistake that I saw.

    Don't forget we've still got some codes to break and a compiler to write!

    Andrew Hayward - 19th May 2003 00:52 - #

  2. Oops I completely forgot about the maths coursework. It looks quite fun though, I'll have a hack at it in the morning. I'm going to give this a category of its own but I haven't got round to it yet (I never wrote myself a category editor so I still have to manually add new categories to the database).

    Simon Willison - 19th May 2003 01:17 - #

  3. Nice introduction, but I have two nitpicks.

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

      Throughout you use the color property without specifying a background-color. This has the potential to cause conflicts with user preferences, and will trigger warnings (which are not very well described) in the w3c CSS validator (possibly scaring newbies).

    2. Your description of absolute positioning doesn't take in to account the possibility of the element being inside another positioned element, and might therefore not be positioned with respect to the page.

      This probably comes under the heading of lies-to-children (simplified first-order explanation), but it would be nice if there was some indication that there was more to it (which would be covered later).

    3. You typoed on ompulsory

    Also, it would be nice if your comment interface had a preview function :)

    David Dorward - 19th May 2003 01:26 - #

  4. Yes, a preview would be nice - I'd forgotten that I'd specified how many nitpicks I'd come up with when I spotted the third!

    David Dorward - 19th May 2003 01:27 - #

  5. You might want to mention the XML way of attaching a stylesheet too. Just in case anyone learning it is looking here for some CSS learning.

    Devon - 19th May 2003 04:00 - #

  6. Great stuff Simon. For those out there like me, just starting. This tutorial really helped me understand some of the things going on with CSS. (As does yours ) http://www.htmlcenter.com/tutorials/tutorials.cfm/ 154/CSS/ Keep 'em coming and thank you.

    james angelton - 19th May 2003 05:24 - #

  7. Nice explanation of descendant selectors. A good start for tutorials.

    Miraz Jordan - 19th May 2003 05:44 - #

  8. Excellent start Simon!!! Just a few comments : 1. a rule may apply to no element at all if the condition represented by the selector matches no element in the document's tree. 2. the selectors .blogentry and #logo are shorthands for *.blogentry and *#logo. The CSS 3 module "Selectors" recommends that the universal selector * is not omitted. 3. I usually prefer the terms "embedded stylesheets" rather than "internal stylesheets". 4. I suggest you use the terminology from CSS 3 Module "Selectors". ie the descendance selector is really the descendant combinator... 5. the descendant combinator is indeed very powerful but also MUCH more expensive, in terms of cpu, time, complexity than the child combinator ">". It is then a pity (and somehow a real shame) that MSIE claims to be CSS compliant and still does not implement it. Daniel, editor/author of the CSS 3 Module "Selectors"

    Daniel Glazman - 19th May 2003 10:53 - #

  9. For example, div#main a matches all links that occur inside <div id="main">

    Not really, it maches all anchor tags; regardless of them being links or not. It's best to start using :link and :visited straight from the start, so we will see less of the a-misuse.

    Even the W3C specs use the 'wrong' selector (CSS2-wise), resulting in red coloured text when clicking on a paragraph (I think they use :active or a:active).

    Jan! - 19th May 2003 14:06 - #

  10. Wow, great feedback. I'll post an updated version with all of the proposed fixes in shortly. Thanks.

    Simon Willison - 19th May 2003 17:13 - #

  11. Some of the Docutils code outputs attributes like class="this that". How do we refer to that in a style sheet? I've been using .this and ignoring that. Any ideas?

    Garth T Kidd - 20th May 2003 06:43 - #

  12. That's actually two classes applied to a single element. You can either use .this, or .that, or if you want to select only elements that have both classes you can use .this.that.

    Simon Willison - 20th May 2003 08:01 - #

  13. Great tutorial, especially on selectors. I hope that, in a later part, you could find out if there's an answer to this: http://dartblogs.com/andrewmg/archives/000123.html #123 .

    Andrew Grossman - 20th May 2003 19:04 - #

  14. Nice work and good content but if I do use large fonts it mixup the text with the right hand menu... bob

    roberto dadda - 1st June 2003 07:55 - #

  15. Ok, i am attempting to get the Heading tag with only one line break.. but the only way I have found is to float: left; however I want the text to align in the center... any way to get the heading tags to break only to the next line.. and not and extra? thanks brett

    brett - 31st May 2005 14:39 - #

  16. kkk

    kkk - 26th September 2005 21:02 - #

Comments are closed.

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

A django site