CSS Is Easy!

Tweet

Cascading Style Sheets. The name alone is intimidating, conjuring up images of cryptic code and syntax, too difficult for the layperson to grasp. In reality, however, CSS is one of the simplest and most convenient tools available to Web developers. In this article, I’ll guide you through the basics of CSS, showing how it can be applied to simplify the task of managing a consistently formatted Web site with minimal headaches.

The Problem with HTML

CSS is a language for defining the formatting used in a Web site. This includes things like colours, background images, typefaces (fonts), margins, and indentation. “But I do all that now with HTML tags,” you might think. “Why do I need CSS?” A valid question, and the best way to answer it is with an illustration of what is wrong with defining such styles using HTML.

A common design choice at present is to use a sans-serif font (like Arial, Verdana, Tahoma, etc.) for the main body text of a site. Since most Web browsers default to a serif font like Times New Roman, creating a complex Web page layout using a sans-serif font will often involve a lot of <font> tags. With the nested table layouts that have become commonplace on the Web, it would not be uncommon to see ten or twenty <font> tags simply dedicated to applying the same font to all of the text on the page. Multiply this by 5 pages for a modest site and we’re in the neighbourhood of one hundred tags. A beefier site might have 50 pages or more, in which case you’re looking at a thousand <font> tags, all dedicated to applying that one basic, consistent style to the text of your document.

Now here’s the kicker: what if your client calls you late one Friday afternoon to say, “Verdana is nice, but everyone uses it. Let’s use Tahoma instead.” Fancy search-and-replace tools aside, you are now faced with the task of adjusting one hundred, one thousand, or even more <font> tags to make what, from your client’s perspective, may seem like a very simple change. You can pretty much kiss that ski weekend you had planned goodbye. Try not to groan out loud – it doesn’t go over well with most customers.

If you know your HTML, you may be thinking that the <basefont> tag, which lets you set the default font to be used throughout a page, provides a nice solution to this problem. Even then, you’d have to adjust one tag for each page of your site. Add another font style to the equation (say you want to use a different font for that fancy navigation bar of yours), and the problem returns in full.

To this problem and others, Cascading Style Sheets are the solution.

Defining Styles with CSS

The basic principle of CSS is to allow the designer to define a style (a list of formatting details like fonts, sizes, and colours) and then apply it to one or more portions of one or more HTML pages using a selector. Let’s look at a basic example to see how this is done.

Consider the following HTML document outline:

<HTML>
<HEAD>
<TITLE> A simple page </TITLE>
</HEAD>
<BODY>

<H1><FONT FACE="sans-serif" COLOR="#3366CC">First Title</FONT></H1>
<P>...</P>

<H1><FONT FACE="sans-serif" COLOR="#3366CC">Second Title</FONT></H1>
<P>...</P>

<H1><FONT FACE="sans-serif" COLOR="#3366CC">Third Title</FONT></H1>
<P>...</P>

</BODY>
</HTML>

This document contains three headings, created using <H1> tags. To make these headings stand out more, I have used <FONT> tags to make them light blue in a sans-serif font (Windows browsers will display them in Arial, for example). Notice the repetition involved, even at this basic level. I had to specify the details of the font I wanted three separate times. Wouldn’t it make sense to define the font just once and then apply it to my headings? Here’s the CSS version:

<HTML>  
<HEAD>  
<TITLE> A simple page </TITLE>  
<STYLE TYPE="text/css">  
<!--  
 
H1 {  
 font-family: sans-serif;  
 color: #3366CC;  
}  
 
-->  
</STYLE>  
</HEAD>  
<BODY>  
 
<H1>First Title</H1>  
<P>...</P>  
 
<H1>Second Title</H1>  
<P>...</P>  
 
<H1>Third Title</H1>  
<P>...</P>  
 
</BODY>  
</HTML>

All of the magic is between the <STYLE> tags in the <HEAD> of the document, where we define our light blue, sans-serif font and apply it to the <H1> tags in the document. Don’t worry about the syntax; I’ll explain it in detail in a moment. Meanwhile, the <FONT> tags have completely disappeared from the <BODY>, leaving our document looking a lot less cluttered. Changes to the style definition at the top of the page affect all three headings, and any other headings added to the page will also take on the style.

Now that you’ve got some idea of what CSS does, let me explain the different ways of using CSS styles in your HTML documents.

Adding CSS Styles to HTML Documents

The simplest way of putting CSS styles in your Web pages is to use the <STYLE> tag, as I did in the example above. This lets you declare any number of CSS styles by placing them between the opening <STYLE> tag and the closing </STYLE> tag, as follows:

<STYLE TYPE="text/css">   
 CSS Styles here  
</STYLE>

The TYPE attribute specifies the language that you’re using to define your styles. CSS is the only language in wide use as of this writing, and is indicated with the value text/css. Another language that is only supported by Netscape 4.x is called JavaScript Style Sheets (JSS), and is specified by text/javascript. Due to the very limited compatibility of JSS, however, it is rarely of any use.

Since Web browsers are designed to ignore any tags they do not recognize, older browsers that don’t support CSS would normally output the CSS style definitions as plain text in the document. To guard against this, it is common practice to enclose the style definitions within an HTML comment tag:

<STYLE TYPE="text/css">   
<!--  
 CSS Styles here  
-->  
</STYLE>

While nice and simple, the <STYLE> tag has one major disadvantage. Specifically, if you want to use a particular set of styles throughout your site, you’ll have to repeat those style definitions in a <STYLE> tag at the top of every one of your site’s pages.

A more sensible alternative is to put those definitions in a plain text file (usually given a .css filename), and then link your documents to that one file. Any changes to the style definitions in that one file will affect all pages that link to it. This provides for our ideal objective of site-wide style definitions, as we mentioned earlier.

To link a document to a CSS text file (say, styles.css), place a <LINK> tag in the document’s header:

<LINK REL="STYLESHEET" TYPE="text/css" HREF="styles.css">

Returning to my original example of three headings sharing a single style, the document would now look like this:

<HTML>
<HEAD>
<TITLE> A simple page </TITLE>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="styles.css">
</HEAD>
<BODY>

<H1>First Title</H1>
<P>...</P>

<H1>Second Title</H1>
<P>...</P>

<H1>Third Title</H1>
<P>...</P>

</BODY>
</HTML>

And the styles.css file would contain the style definition:

H1 {   
 font-family: sans-serif;  
 color: #3366CC;  
}

Like an image file, you can reuse this styles.css file in as many pages as you need. Not only will it save you typing, but it also ensures a consistent look to the headings across your entire site.

CSS Selectors

To every CSS style definition there are two components: the selector, which defines which tags the style will be applied to, and the attributes, which specify what the style actually does. In the previous example, the selector was H1, specifying that the style should apply to all <H1> tags. The remainder of the style definition was the attributes, specifying the font and colour that should be applied by the style. In this section, I’ll describe the basic CSS selector types, giving examples of each.

Tag Selectors

The most basic form of selector is that which we have already seen. By naming a particular HTML tag, you can apply a style definition to every occurrence of that tag in the document. This is often used to set the basic styles that will appear throughout a Web site. For example, the following might be used to set the default font for a Web site:

BODY, P, TD, TH, DIV, BLOCKQUOTE, DL, UL, OL {    
 font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;    
 font-size: 10pt;    
 color: #000000;    
}

This rather long selector is a list of tags, all of which will take on the style definition (font, size, and colour). In theory, the BODY tag would be all that is needed (since all of the other tags appear inside the BODY tag, and would thus inherit the properties), but many browsers don’t properly carry style properties into tables and other elements, so I specified the other elements for the sake of completeness.

Pseudo-Class Selectors

The formatting of the <A> tag in HTML is more versatile than it is for most other tags. By specifying LINK, VLINK, and ALINK attributes in the BODY tag, you can set the colours for the various states of the links in your page (unvisited, visited, and being clicked on respectively). CSS provides its own way of doing this, and adds a fourth state for when the mouse is over the link. Consider the following example:

A:link { color: #0000FF; }
A:visited { color: #FF00FF; }
A:hover { color: #00CCFF; }
A:active { color: #FF0000; }

This code contains four CSS style definitions. Each of the selectors uses what is termed a pseudo-class of the <A> tag. The first applies to all links, and specifies that they should be blue. The second applies to visited links, and overrides the first definition by making them magenta. The third style definition overrides the first two by making links light blue when the mouse is over them (note the name of the pseudo-class: hover), whether they be visited or not. The final style definition makes links red when clicked on. Since it appears last, it overrides the first three so that it will take effect whether the links be visited or not, and whether the mouse is over them or not. Note that the hover pseudo-class is not supported by Netscape 4.x (Netscape 6 does support it, however).

<A> is the only tag that has pseudo-classes under the original CSS1 specification, and all four are demonstrated in the example above. The newer CSS2 spec that is beginning to see support in recent browsers specifies several other pseudo-classes, most of which have to do with how elements look when printed.

Class Selectors

Assigning styles to tags is all well and good, but what happens if you want to assign different styles to identical tags in different places in your document? This is where CSS classes come in. Consider the following style, which makes all paragraph text in the page blue:

P { color:#0000FF; }

Now, what if you had a sidebar on your page with a blue background? You wouldn't want text in the sidebar to be blue as well, because it would be invisible! What you need to do is define a class for your sidebar text and then assign the CSS style to that class instead:

P { color: #0000FF; }
.sidebar { color: #FFFFFF; }

This second rule uses a class selector that indicates the style should be applied to any tag of the sidebar class. The period indicates a class is being named instead of a tag. To create a paragraph of text of the sidebar class, you add a CLASS attribute to the tag:

<P CLASS="sidebar">This text will be white, as specified by the CSS style definitions above.</P>

Now, what if there were links in your sidebar? By default, they'd be rendered just like any other links in your page; however, add a CLASS="sidebar" attribute to the tag, and they'd turn white as well:

<P CLASS="sidebar">This text will be white, <A CLASS="sidebar" HREF="link.html">and so will this link</A>.</P>

That's pretty neat, but what if you wanted to make the links to stand out a bit more by displaying them in bold text? Adding the bold text attribute to the sidebar class would make your whole sidebar bold. You need a CSS selector that selects links of the sidebar class only. By combining a tag selector with a class selector, you can do exactly that:

P { color: #0000FF; }
.sidebar { color: #FFFFFF; }
A.sidebar:link { font-weight: bold; }

Note that we've also used a pseudo-class to specify <A> tags that are links (as opposed to <A NAME> tags that are not).

Note also that our sidebar links are still white – both of the styles pertaining to the sidebar class apply to our sidebar links. If we specified a different colour in the third style, however, links would adopt that new colour since the third selector is more specific, and CSS styles are applied in order of increasing selector specificity.

Incidentally, this effect of applying multiple styles to a single page element is called cascading, and is where Cascading Style Sheets got their name.

Finally, you may find that the link does not appear in bold under Netscape 4.x due a bug in that browser. An alternative approach that achieves the same effect is demonstrated in the next section.

Contextual Selectors

If your sidebar happens to contain a lot of links, it becomes tedious assigning the sidebar class to every single <A> tag. Instead, wouldn't it be nice to use a selector that selected any link appearing inside a paragraph of the sidebar class? That's what contextual selectors are for: selecting a tag based on its context; that is, based on the tag(s) that contain it.

Here's the new CSS:

P { color: #0000FF; }    
.sidebar { color: #FFFFFF; }    
P.sidebar A:link {    
 font-weight: bold;    
 color: #FFFFFF;    
}

And here's the updated HTML:

<P CLASS="sidebar">This text will be white, <A HREF="link.html">and so will this link</A>.</P>

As you can see, a contextual selector provides a list of selectors separated by spaces that must match tags 'from the outside in'. In this case, since the link (matched by the A:link selector) is inside a sidebar paragraph (matched by the P.sidebar selector), the style applies to the link.

Note that to keep the link white, we had to add that colour to the CSS attributes for the links, since the style for the sidebar class no longer applies to the links.

ID Selectors

Similar to class selectors, ID selectors are used to select one particular tag, rather than a group of tags. The tag that you select is identified by an ID attribute as follows:

<P ID="sidebar1">This paragraph is uniquely identified by the ID "sidebar1".</P>

An ID selector is simply the ID preceded by a hash (#). Thus, the following style will make the above paragraph white:

#sidebar1 { color: #FFFFFF; }

ID selectors can be used in combination with the other selector types. The following style, for example, applies to links appearing in the sidebar1 paragraph:

#sidebar1 A:link {
font-weight: bold;
color: #FFFFFF;
}

Other selector types exist but they are not widely used, and support for them in some browsers (especially Netscape 4.x) is buggy at best.

CSS Attributes

In the examples used so far in this document, I've used several CSS attributes like color, font-family, font-size, and font-weight. In this section, I'll direct your attention to the most common CSS attributes supported by today's browsers. Unless otherwise indicated, these attributes should work in Netscape 4 or later and MSIE 4 or later.

An exciting aspect of CSS is that it allows you to achieve many effects that cannot be reproduced using plain HTML. For a complete list of CSS1 attributes (most of which are supported by current browsers), see the Chapter 5 of the CSS1 Spec. For a complete list of CSS2 attributes (many of which are supported by current browsers), see the CSS2 Spec.

border-color

Sets the colour of the border surrounding the selected element(s). The colours for each side may be set individually in IE4 and NS6 or later using border-top-color, border-right-color, border-bottom-color, and border-left-color.

Ex: .errormessage { border-color: #FF0000; }

border-style

Sets the style of the border surrounding the selected element(s). Styles supported by 4.x browsers are as follows: double, groove, inset, none, outset, ridge, solid. The style for each side may be set individually in IE4 and NS6 or later using border-top-style, border-right-style, border-bottom-style, and border-left-style.

Ex: .framed { border-style: ridge; }

border-width

Sets the width of the border surrounding the selected element(s). The style for each side may be set individually using border-top-width, border-right-width, border-bottom-width, and border-left-width.

Ex: .thickborder { border-width: 3px; }

margin

Sets the size of the margin between the outside of an element’s border (if any) and surrounding page elements. The margin for each side may be set individually using margin-top, margin-right, margin-bottom, and margin-left.

Ex: .spacedout { margin: 10px; }

padding

Sets the size of the padding between the inside of an element’s border (if any) and the element itself. The padding for each side may be set individually using padding-top, padding-right, padding-bottom, and padding-left.

Ex: .roomyborder { padding: 10px; }

background-attachment

Specifies whether the background image of an element (in particular, the BODY tag) scrolls with that element, or remains fixed as the element’s contents scroll over it. This attribute can be set to either fixed or scroll. This is not supported in NS4.

Ex: BODY { background-attachment: fixed; }

background-color

Sets the background colour of the selected element(s). May be set to any HTML colour code or name, or transparent.

Ex: .highlighted { background-color: yellow; }

background-image

Sets the background image for the selected element(s). May be set to a URL (note the syntax in the example below), or none.

Ex: .flowery { background-image: url(flowers.gif); }

background-position

Not supported in NS4, this attribute lets you set where an element’s background is positioned. For tiled backgrounds, this specifies the top-left corner of the first tile. For non-tiled backgrounds (see background-repeat below), it specifies the position of the top-left corner of the background image. You can specify one or two percentages, lengths, or positions (left, center, or right), where the first specifies the horizontal position and the second specifies the vertical position. If the vertical position is not specified, it is taken to be 50%.

Ex:
.flowermiddle {    
 background-image: url(flowers.gif);    
 background-position: center center;    
 background-repeat: no-repeat;    
}    
   
.watermark {    
 background-image: url(fadedlogo.gif);    
 background-position: 50px 50px;    
 background-repeat: no-repeat;    
}

background-repeat

Sets the tile method for the background image of the selected element(s). You may choose to tile the background horizontally (repeat-x), vertically (repeat-y), both ways (repeat), or not at all (no-repeat). This attribute is not supported by NS4.

Ex:
TD.sidebar {    
 background-image: url(bar.gif);    
 background-repeat: repeat-y;    
}

color

Sets the foreground colour of the selected element(s). This is usually the colour of the text within the element.

Ex:
P.inverse {    
 color: white;    
 background-color: black;    
}

list-style-type

Sets the type of list to use in a <UL> or <OL> tag. Available types for <UL> tags are circle, disc, and square. Available types for <OL> tags are decimal (1), lower-alpha (a), lower-roman (i), upper-alpha (A), and upper-roman (I).

Ex: UL { list-style-type: square; }

list-style-image

Lets you specify the URL for an image that is to be used as the bullets in a list (<DL>, <OL>, <UL>), or for a particular list item (<DT>, <LI>). A setting of none for a particular list item specifies that the default bullet should be used instead of an image, and can override an image specified for the list as a whole. This attribute is not supported by NS4.

Ex: #listItem1 { list-style-image: url(fileicon.gif); }

list-style-position

Sets whether the list marker (bullet or number) is placed inside or outside the box outlined by the list item text. Another way to look at this attribute is that a setting of inside causes the text to wrap to the beginning of the line, whereas a setting of outside causes the text to wrap to the first character after the list marker on the first line. This attribute is not supported by NS4.

Ex: OL { list-style-position: inside; }

font-family

Sets the font/typeface to be used in the selected element(s). Performs the same function as the FACE attribute of the <FONT> tag. The value should be a comma-separated list of font names in order of preference, with font names containing spaces appearing with quotes around them. As in the <FONT> tag, the last item in the list of fonts should usually be a ‘generic’ font name selected from the following: serif, sans-serif, cursive, fantasy, or monospace.

Ex: P { font-family: "Times New Roman", Times, serif; }

font-size

Specifies the size of the font to be used in the selected element(s). You can specify the font size using one of the available presets: xx-small, x-small, small, medium, large, x-large, xx-large. The presets larger and smaller may also be used to set the font size in relation to the size inherited from a parent element, or the browser default. Alternatively, you can specify a font size in pixels (px), points (pt), ems (em), or as a percentage of the parent element’s font size (%).

Ex: .navbar { font-size: 8px; }

font-style

Specifies whether the font should be rendered normally (normal), or in italics (italic) in the selected element(s).

Ex: EM { font-style: italic }

font-variant

Can be used to display the text all in capital letters, with the lowercase letters of the source code displayed in a smaller font size. A setting of small-caps enables this effect, while normal disables it. NS4 does not support this attribute.

Ex: H1 { font-variant: small-caps; }

font-weight

Sets the boldness of the font in the selected element(s). Most browsers only really support normal and bold, but the CSS spec defines the following values: bold, bolder, lighter, normal, 100, 200, 300, 400, 500, 600, 700, 800, 900, where normal is the same as 400, and bold is the same as 700.

Ex: B { font-weight: bolder; }

letter-spacing

Specifies the spacing between characters in the selected element(s). A value of normal uses the default spacing, whereas positive and negative measurements (pt, em, px) may be used to tighten or loosen the spacing, respectively. This attribute is not supported by NS4.

Ex: .tight { letter-spacing: -0.1em }

text-align

Sets the horizontal alignment of text within the selected element(s) to left, right, center, or justify. The justify option is rendered as left in NS4 for Windows and IE4 for Macintosh.

Ex: .newscolumn { text-align: justify; }

text-decoration

Sets the text in the selected element(s) to be rendered with one of several effects including underline, overline, line-through, or none. NS4 ignores the overline setting.

Ex: A:link { text-decoration: none; }

line-height

Specifies the line spacing for the text inside the selected element(s). Acceptable values include normal (the browser default), a number (where 1 is single-spaced, 2 is double-spaced, and 1.5 is halfway between the two), a measurement (px, pt, em), or a percentage (where 100% is single-spaced). Test this attribute carefully when you use it in your designs, as it is buggy in version 4 browsers.

Ex: .doublespace { line-height: 2; }

text-indent

Sets the indent (or outdent, in the case of a negative value) of the first line of text in the selected element(s). The value may be a measurement (px, pt, em), or a percentage of the parent element’s width.

Ex: P.story { text-indent: 3em; }

text-transform

Sets the capitalization of the text in the selected element(s). A value of none specifies that text should be capitalized as in the source code. capitalize sets the first letter of every word to uppercase. lowercase and uppercase convert all letters to the specified case.

Ex: H1 { text-transform: capitalize; }

vertical-align

Sets the vertical alignment of text within the selected element(s) (bottom or top), or of the selected element(s) in relation to the surrounding text (baseline, middle, sub, super, text-bottom, or text-top).

Ex: .superscript { vertical-align: super; text-size: smaller }

Summary and Further Reading

See? Isn’t CSS easy? In this article I provided a very thorough introduction to CSS; however, I left out many of this powerful formatting language’s more advanced selector features and style attributes for brevity. While you could sort through the CSS1 and CSS2 specs at http://www.w3.org, many of the advanced features described in these specifications remain unsupported in current browsers. The CSS2 spec in particular is only about half-implemented in even the most up-to-date browsers. Features to do with aural presentation and printing just haven’t been a priority for browser manufacturers, even if they have been in the official spec for years.

A better bet would be to pick up a good book on the subject. I recommend Dynamic HTML: The Definitive Reference from O’Reilly, but there are any number of other choices out there, all perfectly good. Just make sure your reference of choice includes information about browser compatibility for every feature discussed. It will keep you from spending long hours scratching your head when something doesn’t work as expected.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

No Reader comments