Cascading Style Sheets Tutorial

Norman Walsh

This excerpt from a World Wide Web Journal tutorial explains how to implement Cascading Style Sheets in your Web documents. Norman Walsh wrote the article while he was Technical Director of Online Publishing at O'Reilly & Associates in Cambridge, Mass. Norm is now a Senior Application Analyst at Arbor Text, Inc.

A CSS1 style sheet contains five basic types of presentational information, called properties:
  • Foreground and background colors and background images.
  • Fonts properties.
  • Text properties (word spacing, letter spacing, etc.).
  • Boxes (margins and borders around block elements, floating elements, etc.).
  • Classifications (control over list styles and the formatting of elements--whether they should be presented inline or displayed as a block, for example).
Beyond the question of what you can specify is the question of what effect will it have. The answer will depend largely on the capabilities of the program that is interpreting the style sheet. In the CSS1 specification, the authors carefully use the term "user agent" rather than "browser" to describe the program that is interpreting the document. The presentation (and meaningfulness) of style elements will be very different if a document is processed by a text-only browser or a braille reader or a speech synthesis tool than when it is processed by a full color, graphical browser. (This article is not a specification, and I've chosen to use the term "browser" rather than "user agent" because it is reasonable to be less formal in this context. For the record, I'm committed to supporting every effort to make Web documents accessible by everyone, and I really mean "user agent" when I say "browser.")

Within a given browser, you may encounter other limitations. Most of the properties that expect a size or length accept both positive and negative values as well as percentages. Each browser is free to impose implementation-specific limits on the acceptable range of values. Different browsers are also likely to do slightly different things when they encounter conflicting or illogical property values. Browsers may even implement different behaviors depending on the language used by the document or local user settings.

The bottom line is that styles are suggestions, hints if you will, to the browser. There is no provision for enforcing any aspect of the presentation. You can no more guarantee that another user viewing your document with a style sheet will see precisely the same thing you see than you can currently guarantee if they are viewing your document without a style sheet on different browser or platform.

How Do You Include Your Style Sheet?

Style information can be included in a document in several ways:

  • With a style sheet <LINK> in the <HEAD> of the document:
 <LINK REL=STYLESHEET TYPE="text/css" HREF="http://...">
  • In the <STYLE> element in the <HEAD> of the document.
  • Directly in the STYLE attribute of individual elements of the document. This method is discouraged since it mixes presentation information directly into the document. Note that style information can be provided for a individual element, regardless of its context, through its ID.
  • The @import command in a style sheet allows one CSS1 style sheet to explicitly import another.
How Do You Assign Styles to Elements?

However the style sheet is imported, the content of the style sheet itself is a text document containing rules and possibly comments (in the C language style /* comment */ notation).

Simple Style Rules

A simple style rule has the following form:

element-name { property: list }
where the element name is the name of an HTML tag (H1, P, DIV, etc.) and the property list is the associated style commands. (We'll cover the specific properties in more detail a little later.)

Inheritance

Many of the property values applied to an element are inherited by elements placed inside it. For example, if you specify that text in headings should be red, emphasized text in the headings will also be red.

Elements In Context

Although there is no general mechanism for identifying elements in context (parents, children, siblings, etc.), a simple scheme is provided for specifying presentation based upon parent elements (you can specify formatting for EM inside of H1, for example, as distinct from EM elsewhere).

If you list a series of element names, instead of a single name, in a formatting rule, that rule applies only to elements that have all of the parents listed. For example,

DIV H1 EM { properties }
assigns the specified properties to EM only if it occurs inside of an H1 inside of a DIV. Note that other intervening elements are possible; this rule would apply to an EM inside of an H1 inside of a TABLE inside of a DIV as well. If multiple nestings apply, the longest nesting wins.

Subclassing Elements

Sometimes it is desirable to treat specific instances of an element differently. For example, you might want to present warnings in a distinct way or have special formatting for links to URLs that are on another server.

Since HTML does not provide a great richness of structure for this purpose, CSS1 has hooks to the CLASS attribute, which can be placed on any element to assign a specific role to an element. For example, the preceding cases might be coded like this:

<P CLASS=warning> 
<A CLASS=offsite HREF="http://...">...</A>
To specify the styles for elements of a particular class, add the class name to the element name with a period in the style sheet:
P.warning { properties } 
A.offsite { properties }
Subclasses and nesting are independent operations. You can mix them freely in your style sheet.

Subclassing by ID

Another form of subclassing is by ID. This is the mechanism that allows you to avoid embedding specific style information in your document even for a unique element. If you have a specific element that must be uniquely treated, you can give it an ID:

<P ID="special-case">
and then assign style information to that element with a #:
 #special-case { properties }
Note that IDs are required to be unique within a document. This requirement may not be enforced by current browsers, but it is a requirement for a truly conforming document. If you have several elements that need special treatment, that's a CLASS.

Pseudo-Classes

Some aspects of the presentation are not dependent strictly on the structure of your document but are rather a function of the browser or of user interaction. You may wish to control the formatting of the first line of a paragraph, for example, or the display of visited links.

In CSS1, these aspects of presentation are controlled by pseudo-classes. Like classes, they are specified with the element in the style sheet. Pseudo-classes use : as the separator character. Classes and pseudo-classes may be mixed:

A:visited { properties } 
P.initial:first-letter 
{ properties }
The first example here changes the properties of visited HTML links, the second changes the properties of the first letter of paragraphs with the CLASS "initial".

Conflicting Style Sheets: The Cascade

One fact that cannot be overlooked when considering style sheets is that both the publisher and the reader may wish to specify a style. Publishers frequently have a distinctive look that they wish to be reflected in all of their publications, and readers may have expectations as well, motivated by limitations of their environment or simple matters of artistic taste. (Personally, for example, I wish to specify that the background of all Web documents be white. I have a grayscale monitor at home, and most colored or graphical backgrounds on Web pages result in black-on-black text on my display.)

In addition, using modular style sheets is bound to result in occasional conflicts. It is necessary to know how these conflicts will be resolved (and frequently desirable to be able to specify how they should be resolved).

This raises the question of who gets control and this is where the word "cascade" comes from in Cascading Style Sheets. CSS1 includes a scheme for assigning priority to each style element. In every case, the style with the highest priority wins.

CSS1 is biased toward the publisher's styles. There is a single level of negotiation between the publisher and the reader; styles may be identified as "normal" or "important." If two styles have the same priority, the publisher's style sheet wins; otherwise, the higher priority style wins. Note, however, that browsers should provide a mechanism for disabling style sheets altogether so, in fact, the reader has final control.

Whether or not you agree with the philosophy that CSS1 uses, it's important to realize that this is a difficult problem, and there is no perfect solution. In some cases, the publisher may feel that absolute control is required (for example, if there is a legal obligation that warnings not be presented in a font smaller than 8 point), and in some cases, the reader must have control (for example, I simply cannot read dark red on black text).

A Closer Look at Properties

A property in CSS1 consists of a property name followed by a property value. The property name and value are separated by a colon. Some properties may have more than one value, in which case the value selected is dependent on some local condition (the accessibility of a particular font or image, for example).

Multiple properties may be specified by including multiple property name, value pairs separated by semicolons. The following example selects yellow on blue text for top-level headings and an italic font for paragraphs in block quotes:

H1 { background: blue; 
     color: yellow } 
BLOCKQUOTE P { font-style: italic }
The following sections describe some of the properties that are available.

Foreground and Background Colors and Background Images

There are two properties for specifying colors: color and background

The color property controls the foreground color of an element. Usually this is the color of the text of an element. Colors may be identified either by name or by RGB value.

The background property controls the background color or texture of an element. When an image is specified for use as a texture, its position, scrolling aspect, and repeatability can be controlled.

Fonts Properties

There are five properties that control which fonts are used:

font-family

Identifies the font family, or typeface, to use. A series of names may be requested; the first available font will be used. There are five classes of "generic" fonts that may be specified as a last resort, serif for serifed faces like Times Roman; sans-serif for san-serif faces like Helvetica; monospace for fixed-width fonts like Courier; cursive for swash faces like Zapf Chancery, and fantasy for other hard-to-classify faces like Grunge or Western.
font-style
Identifies the style of the face, normal, italic, or oblique.
font-variant
Identifies another variation on the face--either normal or small-caps in CSS1.
font-size
The size of the face. Font size may be specified in absolute units or relative to the "current" size.
font-weight
The weight or boldness of the font, specified with either a keyword (bold or bolder, for example) or as a member of the ordered series 100, 200, 300, . . . , 900, where higher numbers are correspondingly darker.

Text Properties

Several text properties are available:

word-spacing

Modifies the default inter-word spacing.
letter-spacing
Modifies the default inter-letter spacing.
text-decoration
Selects underlining, overlining, link-through, or blink attributes (with additional, unspecified decorations anticipated from vendors).
vertical-align
Adjusts the vertical alignment of an element.
text-transform
Shifts text to uppercase or lowercase.
text-align
Specifies left, right, center, or justified alignment.
text-indent
Determines the amount of indentation on the first line of a block of text.
line-height
Specifies the distance between the baselines of consecutive lines of text.

Boxes

The formatting model suggested by CSS1 is one of concentric rectangles. Each element has a margin, inside the margin is an optional border, inside the border is optional padding, and inside the padding is the actual formatted content of the element. The box properties allow you to specify the nature of the rectangles and determine how the content of the element is formatted to fit in the space provided.

margin margin-bottom,
margin-left margin-right

Determine the size of the top, bottom, left, and right margins. Setting margin adjusts all of the margins simultaneously.
padding padding-bottom,
padding-left padding-right

Adjusts the amount of padding on the top, bottom, left, and right sides of the element. Setting padding adjusts all of them simultaneously.
border border-bottom, 
border-left border-right

Selects the nature of the border on the top, bottom, left, and right sides of the element. Setting border adjusts all of borders simultaneously. You can specify the size, color, and style of the border.
width height
Identifies the width and height of the rectangle that contains the formatted content. Images should be scaled to the specified size, if necessary.
float
Identifies an element that should float to the left or right of a flow of text, allowing the text to flow around it.
clear
Specifies where floating elements may occur with respect to the element. For example, specifying clear: left indicates that there may be no floating elements to the left of the element; this will force the element to start below an image floating on the left side of the display, for example.

Classifications

There are three classification properties, display, list-style, and white-space:

display

Allows you to specify what category of object an element belongs to: is it a block element, like a heading or paragraph; an inline element, like emphasis or anchors; or a list-item block element, like LI. An additional category is none, which indicates that the content of the element should not be displayed at all.
list-style
Influences the selection of numbers or bullets for lists. In addition to selecting one of the built-in enumeration or bullet styles, you can specify an image for use as the bullet character. You can also influence the position of the list mark with respect to the flow of the text. An outside list mark occurs to the left of the entire list item, whereas text wraps under an inside mark.
white-space
Identifies how the line breaking of an element is to be accomplished. Possible values are normal, where white space serves merely to delimit elements that are formatted according to the alignment of the surrounding element; pre, where all white space is significant; and nowrap where white space serves primarily as a delimiter, but no wrapping is done except where <BR> elements occur.

A Sample Style Sheet

Finally, Example 1 shows how we might code a CSS1 style sheet for the style I specified in the section "Style Sheets are the Presentation."

Does it work? Sort of.
BODY { background: blue; 
color: white; 
font-family: times, serif; 
font-size: 10pt } 
A:link { color: red } 
A:visited { color: yellow } 
H1 { font-family: arial, helvetica, sans-serif; 
font-size: 20pt; 
font-style: bold } 
DIV.warning { margin-left: 0.5in; 
margin-right: 0.5in; 
color: yellow; 
background: red } 
BLOCKQUOTE { background: white; 
color: black; 
font-style: italic; 
font-size: 8pt } 
/* Background color isn't inherited, so we repeat it 
on paras inside block quotes. 
*/ 
BLOCKQUOTE P { background: white } 
UL { list-style: url(fancybullet.gif) disc } 

Support for style sheets in Internet Explorer 3.0 is disappointingly thin. Microsoft seems not to have supported style attributes on all elements (setting colors on block quotations has no effect, selecting a graphical bullet for lists does not work, etc.). I can find no documentation of what they do support, so it's a sometimes tedious process of trial-and-error to build a style sheet that works, and there is no warning when a style is syntactically incorrect although that error may have a wide-reaching effect on the style sheet.

Gnuscape Navigator does the best it can, but the text-only environment of GNU Emacs is fairly limiting (better support may be available in XEmacs, I haven't tried).

Conclusion

Despite these difficulties, I'm still a fan. It will get better, and the time to start experimenting is now. The examples that I presented here are fairly plain. For some examples of much more dramatic effects, see the Microsoft Style Gallery.

In this article, I've tried to give an overview of CSS1, but I haven't tried to supply all of the details. For more information, start at the aforementioned W3C Web Style Sheets page; it contains numerous links to information about CSS1 and style sheets in general.