Cascading style sheets are, or more properly is, a standard defined and promulgated ("huh huh, he said 'promulgated'!") by the World Wide Web Consortium or W3C. As of this writing (February, 2002), the W3C's CSS "home page" is a virtually unusable mess located at http://www.w3.org/Style/CSS/. That page is not the worst example of malignant CSS abuse that I've seen, but it'll do.
Most people use the abbreviation CSS for the sake of convenience. In theory, CSS should separate presentation details from document structure: Tags "should" be used only if they have some logical meaning. Sheer decoration "should" be done with CSS. In practice, there's no good place to draw the line. Ideally, we'd do everything in XML with appropriate DTDs and convert it into HTML on the fly, but like all software development everybody's got a deadline and it's just a mess. Any discussion of the issue degenerates rapidly into hair-splitting and holy wars.
The current (Feb 2002) version of the standard is CSS2, which theoretically superseded the older CSS1 in May, 1998. CSS1 itself "became a W3C recommendation" in December, 1996. In December, 2001, something called "the CSS Mobile Profile" became something called a "W3C Candidate Recommendation"1.
In practical terms, what's nice about CSS is that you can put all or most of your display parameters in one place: If you want your paragraphs indented, you can use CSS to alter the behavior of the standard <p> tag globally such that it's got an indent. If you get tired of that later, you can make one change in one place to get rid of it everywhere. CSS can be embedded in your HTML file, or it can be in a separate file and be linked to many HTML files. Naturally, the CSS can be generated dynamically just like any other file.
Like HTML, CSS is purely declarative. It's not a programming language. For all that, the syntax is relatively elaborate (more so than LISP, for example, and LISP is Turing complete).
When you define CSS attributes, you associate them with an HTML tag, or with a "class". A stylesheet class can be associated with a single tag, with several tags, or with no tag. It can be associated with a context, as well: For example, you could make the content of <li> tags green if and only if the <li> tag is found within an <ol> list.
A style definition is just a list of attribute names with values. Attribute names are defined by the standard, as is the form of their values: CSS can't be used to extend itself. There are attributes defined for spacing around elements, position of elements, font styles, foreground and background colors, and background images. I will not attempt to provide an exhaustive list of attributes and their values. There should be such a list under CSS attributes.
Here's a very simple example which will indent the first line of every <p>-tag-enclosed paragraph by sixteen pixels:
/* Comments look like this. There is no syntax for
"to end of line" comments: // is a syntax error.
*/
p {
text-indent: 16px;
}
The text-indent attribute indents the first line of the text contained by the tag or class you throw it at. It's a "length" attribute, so its value must be a number followed by a unit, with no whitespace in between (if your browser tolerates whitespace between number and unit, it is broken). The following length unit identifiers are defined:
- em The width of an em dash in the current font.
- ex The height of a lower-case 'x' in the current
font.
- in One inch.
- cm One centimeter.
- mm One millimeter.
- pt One point (1/72 of an inch).
- pc One pica (twelve points).
- px One pixel.
Those are mostly typography things and mostly print-oriented, except for pixels. The size of an "inch" on your screen doesn't necessarily correspond to reality. An "inch" on a page coming out of your printer has a fighting chance at corresponding to reality, but don't count on that either2.
When you assign a property value, it overrides the default for that property. Other properties are unaffected. You can define properties for the same tag in more than one place. Here's an example:
/* With commas, you can apply the same attributes to
several tags at once (this is true also of classes,
which we'll get to in a moment).
*/
h1, h2, h3, h4 {
/* Don't quote lists of font names */
font-family: Tahoma,Verdana,Helvetica,Arial;
}
h1 { font-size: 13pt; }
h2 { font-size: 12pt; }
h3 { font-size: 11pt; }
h4 { font-size: 10pt; }
In addition to defining properties for all instances of a tag, you can also define properties for only some instances of a tag. There are two ways to do this: Defining a class, and specifying the context. First, classes:
p.indented {
text-indent: 16px;
}
.highlight {
background-color: #ffffe0;
}
Here we have two classes: indented is defined only for the paragraph tag, and highlight is defined for any tag. You invent class names yourself. There are no standard ones. You'd use those classes like so:
<p class="indented">On my summer vacation, I abducted
a mime and made him sing <b class="highlight">sad
songs</b> at gunpoint. </p>
The "class" attribute of a tag specifies one or more CSS classes. If you've got more than one, they must be separated by whitespace. Since the highlight class specifies no tag, you can use it with <b> or with any other tag. If you want just the attributes of that class, without the default behavior of any tag, you can use the <span> tag. <span> exists for this purpose and has no characteristics of its own.
You can also define attributes for several tags and/or classes at once:
p.indented, p.other, div.indented {
text-indent: 16px;
}
Context is weirder, and less used: For a tag or class, you can define characteristics which will apply only when the tag or class appears within some other tag or class. Here's an example which will cause nested italics not to be italicized (that's the Right Thing, by the way):
/* Even nesting depths (2, 4, 6) are not italicized */
i i, i i i i, i i i i i i {
font-style: normal;
}
/* If we only talk about even depths, odd depths will
be normal, too: After all, something nested three
deep is also nested two deep. Therefore, we must
explicitly say what we want for 3, 5, and 7.
*/
i i i, i i i i i, i i i i i i i {
font-style: italic;
}
Note the placement of commas: "i i i" means "i within i within i". The "even nesting" definition applies to "i within i", "i within i within i within i", and the same for six of 'em. With that CSS, we can do the following example:
<p>Normal <i>i level one <i>i level two <i>i level three</i>
i level two</i> i level one</i> normal again.</p>
The example will display like this (in Netscape 4, Mozilla, or IE5, at least):
Normal i level one i level two i level three i level two i level one normal again.
Remember, the context can be any tag or class. Take for example the following:
.highlight {
background-color: #ffffe0;
}
div.ghastly {
/* Colors can be defined with rgb(), too: The values
can be integers from 0 to 255, or else percentages
identified with a trailing '%'.
*/
background-color: rgb(128, 64, 32);
margin: 20pt;
font-weight: bold;
font-size: 40pt;
color: #00ff00;
font-family: Comic Sans,Fugly Obscene,Fugly Immoderate,Courier;
}
p.highlight .highlight, div.ghastly .highlight {
background-color: #e0e0c0;
}
In this case, we might have highlighted text scattered througout a file, and we might be highlighting whole paragraphs too. If a whole paragraph is highlighted, it may (we'll assume) contain other bits of highlighted text. When that happens, we'll still want those other bits to have a background color that contrasts with that of the text around them. You could define a darker-highlight class and use that where needed, but it's much easier and safer to let the client software do the scut-work.
When you define CSS stuff in a file all by itself, it is what it is. When you want to embed it in an HTML file, you need to put it in a <style> tag, like so:
<!-- text/css is a [mime type] -->
<style type="text/css">
<!--
/* Don't forget to put HTML comments around it, for the
benefit of style-ignorant web browsers.
*/
p.fugly {
background-color: black;
color: yellow;
font-weight: bold;
}
-->
</style>
If you want the HTML file to use a separate CSS file, link it like so:
<link rel="stylesheet" type="text/css" href="stylefile.css" />
You can also apply CSS to a tag "
inline" with the
style attribute:
<p style="text-indent: 16px; color: blue;">Blah blah blah.</p>
Note that "can" and "should" are two wholly different things: If there's any chance that you'll be applying that set of styles in more than one place, define a class and save yourself a maintainance nightmare.
That should be enough to get you started.
1 http://www.w3.org/Style/CSS/
2 Thanks to Cletus the Fetus for joggling my elbow about printers. Thanks also to Cletus for reminding me that the 'C' in W3C is for "Consortium", not "Committee".
- References
- Mozilla version 0.9.5
- Internet Explorer version 5.5
- Netscape Navigator version 4
- Chapter nine and Appendix C of HTML: The Definitive Guide 3rd ed.,
Chuck Musciano and Bill Kennedy, O'Reilly Press.
- W3C CSS home page (http://www.w3.org/Style/CSS/)
- W3C CSS2 spec (http://www.w3.org/TR/REC-CSS2/)