glasshaus: The Web Professional's Handbook

This sample chapter is taken from glasshaus' The Web Professional's Handbook, ISBN 1904151221.

Chapter 2: Cascading Style Sheets

Stylesheets are templates containing rules that describe how a browser should display documents on screen, in print, or in other media. Cascading Style Sheets (CSS) are the major tool for controlling the presentation of XHTML and XML documents. Clearly, without some control of presentation, the World Wide Web would be much less robust and visually pleasing an experience than it is today. There are other presentational tools besides CSS, but they have disadvantages.

XSL (Extensible Stylesheet Language) is an XML-style language that can transform XML into XHTML/CSS, but cannot be used directly in an XHTML document. For more details, see Chapter 5.

CSS was introduced in August 1996, when Microsoft released the first commercial browser with CSS support, Internet Explorer 3. IE 3 actually predates the designation of CSS Level 1 (CSS1) as a World Wide Web Consortium (W3C) recommendation by several months – CSS1 became a Recommendation in December 1996 and is the first of several versions of CSS that exist today. Netscape released its first CSS1 browser, Navigator 4.0, in June 1997. Opera followed with support in version 3.5 in November 1998.

CSS1 includes the basic presentation tools: control of font, color, text, and the “box model” of content/padding/border/margin. Browser support has been slow in following, however, and it is only in the last few years that the main browsers have approached a full, robust implementation of support for CSS1. Adoption of CSS by developers has expanded as browser support has increased. As that has happened, the ability to properly present CSS style has become nearly as important as presenting XHTML content correctly.

In May 1998 the W3C released CSS Level 2 (CSS2) as a Recommendation (http://www.w3.org/TR/REC-CSS2/). CSS2 builds upon CSS1 and adds more functionality, such as media types (including print stylesheets), additional positioning control, more internationalization features, generated content, and cursor controls. It also corrects errors in the CSS1 specification. In general, browser support for CSS2 is less than for CSS1, but the core of CSS2 is supported in the modern, mainstream browsers such as Internet Explorer 6, browsers based on the Gecko rendering engine (chiefly Netscape 6+), and Opera 6+.

At the time of writing, CSS2 Revision 1 (CSS2.1) is in development as a Last Call Working Draft of the W3C (http://www.w3.org/TR/CSS21/). Its purpose is to correct errors in CSS2 and to be “a ‘snapshot’ of CSS usage: it consists of all CSS features that were implemented interoperably at the date of publication”. To that end, it removes some functions from CSS2 that had found no implementation to speak of in commercial browsers.

Some of those functions have been moved into CSS Level 3 (CSS3). CSS3 is currently in development as a group of 28 modules. The modules are in varying stages of completion at the time of writing, from having no public Working Draft yet produced to having achieved Candidate Recommendation status. The current status of CSS3 can be found at http://www.w3.org/Style/CSS/current-work/. In this chapter, discussion of CSS will refer to CSS2.1, as it is very similar to CSS2. Where appropriate, differences between versions 2 and 2.1 will be noted.

Using CSS in Documents

The aim of using CSS is to separate the content of a page from its presentation. Ideally, the CSS will contain all the style rules for a web site: fonts, colors, layout, etc. The XHTML will be strictly for tagging the content: marking up headings, paragraphs, etc. The advantage is that we can easily alter the entire presentation by changing the CSS, rather than having to change presentational elements buried in each individual XHTML page of a given site.

There are three primary ways to use CSS in your document. Your CSS rules can be:

Additionally, the @import method can involve using both an external CSS file, and calling that file via a <style> element.

External CSS Called Via <link>

The most powerful feature of CSS is in its use for site-wide presentational management. One CSS file can contain all the styles for a web site. Changing just that one CSS file can make sweeping changes across the entire site. This is generally the best way to implement CSS on a site.

The file is called in the XHTML page via a <link> element located in the <head>, whose typical format is:

<link href="path_to_css_file" type="text/css" rel="stylesheet" />

The CSS file contains the CSS rules typically formatted as:

selector { property_name : property_value; }

An example would be:

p { font-size : small; }

Alternative Stylesheets and Switching Styles Called Via <link>

It is possible to designate alternative stylesheets in XHTML, so that in theory a user can switch between styles according to their personal preferences or accessibility needs (such as setting a larger default font size, or forcing all hyperlinks to appear underlined for easy identification). To tag the alternative stylesheet as such, the rel attribute in the <link> tag is changed to read "alternate stylesheet". The title attribute is also set to give a name to the alternative stylesheet. For example:

<link href="path_to_alternate_css" type="text/css" rel="alternate stylesheet"
      title="My other style sheet" />

Browsers that currently have a built-in mechanism in the user interface for switching between stylesheets include Netscape 6+ (View > Use Style) and Opera 7 (View > Style).

Thus web sites wanting to offer this feature to their visitors will often include a scripted widget to make style changes and maintain the selected style while moving from page to page within the site. Such scripts can either run client-side or server-side. For good examples, read “Alternative Style: Working with Alternate Style Sheets” on A List Apart (http://www.alistapart.com/issues/126/) for a client-side (JavaScript/DHTML) program, or visit http://alterior.net/archives/000021.php for an example of a server-side script (PHP in this instance).

Placed within a <style> Tag

CSS rules can be embedded in the <head> of an XHTML page via the <style> tag. The format is:

<style type="text/css">
selector { property_name : property_value; }
</style>

Generally, the rules here will apply only to the particular page that the <style> tag appears on. See the @import section below for an exception to this. Since the rules will only apply to the given page, this is a less powerful implementation of CSS. You lose the ability to change all your pages by changing one CSS file; again @import excepted, see that section for more.

Commenting Out <style> Blocks

In HTML 4, it is a common practice to wrap an HTML comment around the content of a <style> tag, as follows:

  <style type="text/css">
    <!--
    CSS rules here
    -->
  </style>

The purpose of this is to hide the CSS rules from older browsers that did not support the <style> tag. The <style> tag was first supported in Internet Explorer 3, Netscape 4, and Opera 3.5. Older browsers might attempt to render the CSS rules right onto the web page as plain text.

In XHTML, this type of commenting is not permitted unless you wrap all the <style> tag content (including the comment tags) in a CDATA section marker, such as:

  <style type="text/css">
  <![CDATA[
    <!--
    CSS rules here
    -->
  ]]>
  </style>

Leaving out the CDATA marker can be dangerous, depending on your server’s configuration. An XHTML file can be served with an application/xhtml+xml MIME type, instead of the text/html MIME type typically used today for backward compatibility with older browsers. With an XML MIME type an XML parser, if it finds the comment tags without CDATA around them, will dutifully obey the comment tags and ignore all the CSS in between.

Some browsers, however, will not support and recognize the CDATA marker, and wind up ignoring the CSS rules entirely. At this point in web development and browser history, it is best to simply leave the comment tags out. Any browser old enough to choke on the <style> tag is going to be one that infrequently, if ever, visits your web site anyway.

Within the style Attribute

Almost any XHTML element can take the style attribute (exceptions: <base>, <basefont>, <head>, <html>, <meta>, <param>, <script>, <style>, and <title>). CSS rules can be written in the attribute in this format:

<element style="property_name: property_value;">

The CSS rules only apply to that specific element. So if, for example, you have this piece of code:

<p style="color: red;">CSS is very helpful.</p>

only this paragraph will have red text and other paragraphs would not.

Inline styles as a whole are reminiscent of embedding presentational markup such as <font> directly into a document, and probably just as undesirable. In fact, the style attribute is deprecated in XHTML 1.1 and is completely gone from the current Working Draft of XHTML 2.0, so using inline styles is definitely not a future-proof practice.

@import

The @import rule is used to import CSS from other external stylesheets. In that regard it is similar to the “link to an external stylesheet” method in that both access an external CSS file. @import uses a different syntax, and is easier to use when an XHTML page is linked to multiple stylesheets.

@import has two equivalent syntaxes:

@import "path_to_css_file";

@import url("path_to_css_file");

The choice of syntax can be important as older browsers either do not support both syntaxes (most notably, Internet Explorer will ignore CSS imported via the @import "path_to_css_file"; method), or do not support @import at all. See the next section Hiding CSS from older browsers for details.

The @import rule can either be inside an external CSS file, or inside a <style> tag. In both cases, the @import rule must be the first CSS rule that appears. Other CSS rules can follow afterwards in the CSS file or in the <style> tag.

Hiding CSS From Older Browsers

With CSS implementation being incomplete and buggy in earlier browsers, it is often necessary to hide advanced CSS from these older browsers, so they don’t act on CSS code that they would only implement incorrectly or break the page.

There are a number of ways to do this, but one of the most common is the use of @import. The @import rule is completely unsupported by Internet Explorer 3 and Netscape 4, both of which will ignore the CSS to be imported. The @import "path_to_css_file"; syntax will also be ignored by Internet Explorer 4, whose CSS support is better than version 3 but still spotty.

Another common technique is to <link> to a “safe CSS” so that the older browsers can see and act upon it. The <link> is followed by an @import, usually via a <style> tag, of the more advanced CSS. For example:

  <link href="safe_css_file" type="text/css" rel="stylesheet" />
  <style type="text/css">
    @import "advanced_css_file";
  </style>

This technique works well to segregate the more current browsers with good CSS support from the older ones that lack it. Internet Explorer 4.5 on the Macintosh can be an interesting exception. It understands @import but is old enough to sometimes have problems with the CSS you would typically be trying to hide by using @import. You should take that into account if this browser makes up a significant portion of your site traffic. Do thorough testing of your imported CSS in IE 4.5 on Macintosh.

Another common method of hiding CSS is by defining a media attribute on the <link> tag.

CSS for Different Media

CSS files can be specified as only to be used with certain media. The most common media types in use are screen, meaning computer screens, and print, for printed pages and print previews within browsers. Other types include:

By adding a media designation, you can hide your CSS from browsers that don’t understand the designation. The syntax on a <link> tag would be as follows:

<link href="path_to_css_file" type="text/css" rel="stylesheet" media="all" />

This will cause Netscape 4 to ignore the CSS file. If a media attribute is set, Netscape 4 will only act on the CSS if the media is set to “screen”.

There are other methods of hiding CSS from browsers. Some depend on browser bugs. Others use advanced CSS2 syntax that less compliant browsers will not understand. For a good list of additional methods and a breakdown of what browsers they are effective against, visit http://pixels.pixelpark.com/~koch/hide_css_from_browsers/.

CSS in Internet Explorer 3 and MSN TV

Two other browsers can provide CSS compatibility issues: Internet Explorer 3 and MSN TV (formerly WebTV). Both have limited CSS abilities and a number of bugs. It is generally best to hide CSS from these browsers unless you have a specific need to support them. Neither browser supports the @import technique so CSS can be hidden in this way.

If you do need to support these browsers, the following are good references:

The Basics

To illustrate some basic CSS, we will walk through an annotated stylesheet. It is a template that can be used as a starting point for building a CSS file for a web site. It sets a number of default styles that an author would almost always change as the site developed, but the default styles provide a baseline from which to start.

This CSS is written for current browsers with good CSS support: Internet Explorer 5+, the Gecko family of browsers (chiefly Netscape 6+), and Opera 6+. Some of the code here will not work in older browsers or will break undesirably, most typically in Netscape 4. Notes about some of the potential problems are included in the annotation.

Please also refer to the CSS Property Reference section later in this chapter for details of any CSS properties listed here, and to the CSS Selector Reference for details about the syntax.

html {
  background : #FFFFFF;
  color : #000000;
  display : block;
  margin : 0;
  padding : 0;
}

Here we set the background color of the page as white, and the text color to black. It is preferable to do this on <html> and not on <body>. This is because if you have a small page where the <body> content is smaller than the canvas, and the colors are on <body>, then <body> will have your defined background color and the rest of the canvas (the <html>) will have whatever the browser default background color happens to be. The display : block; rule is set throughout on block-level HTML elements, simply to define the default. Margin and padding are set to zero as a basic default as well. Notice that the properties appear on separate lines for ease of reading.

body {
  display : block;
  font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
  line-height : 1.33;
  margin : 0;
  padding : 0;
  font-size : medium;
}

Here we have set the suggested fonts for use on the page using the font-family property. Verdana is a popular Windows screen font, Geneva a good Macintosh font, Arial another screen font prevalent on Windows and Macintosh systems, and Helvetica a common Unix font. sans-serif is at the end to suggest that if the user’s system has none of these fonts, the browser’s default sans-serif font should be used.

Line-height is a measure of the whitespace between lines. In print, this is commonly called “leading”. The 1.33 tells the browser to set the line-height to 1.33 times the height of the font in use. Note that line-height should not be applied here if the CSS is for use with Netscape 4. Bugs it has with line-height will cause images on the page to be moved from their correct position, including on top of the page text. The font size is set to a basic default, medium .

a:link {
  background : transparent;
  color : #0000FF;
  text-decoration : underline;
}

The color of unvisited hyperlinks is set to blue, and the background is set to transparent. It is desirable to always set background and color together, even if just to set background to transparent. If background is not set, there is a potential for a display problem if a visitor has configured their browser to change the page background to something besides what you have defined. The text-decoration rule declares that the link should be underlined, which most browsers will do anyway.

a:visited {
  background : transparent;
  color : #990099;
  font-variant : small-caps;
  text-decoration : underline;
}

This section is for visited hyperlinks. As a visual aid, the rule suggests that the text of visited links be rendered in small capital letters (small-caps). This gives the visitor another cue (besides the color change) as to which links are visited and which are not. This rule would not work in Netscape 4 or Opera 6; those browsers would just ignore it.

a:hover {
  background : transparent;
  color : #000000;
  text-decoration : underline overline;
}

This section sets styles for when a link is being hovered over with the mouse. Here the rule says that besides the typical underline, we will add an overline (a line on top of the text) during a hover. Netscape 4 does not support hover and will just ignore these rules. This is a good reason to avoid the trick of setting text-decoration to none on a:link and a:visited and then setting a:hover to underline. Since Netscape 4 cannot do hover, the links will never appear underlined and can be harder to identify.

a:active {
  background : transparent;
  color : #FF0000;
  text-decoration : none;
}

This section defines styles for when a link is active, that is, being clicked on. Note that Netscape 4 does not support and simply ignores a:active.

address {
  display : block;
  margin : 0;
  padding : 0;
}
/*applet { display : inline-block; }*/

The above rule illustrates the syntax of CSS comments: /* Commented material here. */. In this case (and some others to follow) rules using display : inline-block are commented out because inline-block is new in CSS2.1 and does not exist in CSS2. Note also that rules with single properties tend to appear on one line, as here.

blockquote {
  display : block;
  margin : 0;
  padding : 0;
}
caption {
  display : table-caption;
  text-align : center;
}

For <caption>, we have set the clear default of displaying the content as table-caption (since the <caption> tag is for captioning a <table>). As the name implies, text-align defines how to align the text. Here we have chosen to center it. Other default display settings for table elements are scattered throughout the CSS.

cite { font-style : italic; }

The <cite> tag is typically used for tagging the names of works, such as book or movie titles. In print those are usually italicized, so the CSS uses the font-style property to suggest the same effect.

code { font-family : monospace; }

For the <code> tag (typically for marking computer code), we have used font-family again to change the font to a monospace font.

col { display : table-column; }
colgroup { display : table-column-group; }
dd {
  display : block;
  margin : 0;
  padding : 0;
}
del { text-decoration : line-through; }

As <del> is for marking a deleted item, text-decoration here requests a line-through effect: a horizontal line through the middle of the tagged text.

dfn { font-style : italic; }
dir {
  display : block;
  margin : 0;
  padding : 0;
}
div {
  display : block;
  margin : 0;
  padding : 0;
}
dl {
  display : block;
  margin : 0;
  padding : 0;
}
dt {
  display : block;
  margin : 0;
  padding : 0;
}
em { font-style : italic; }
fieldset {
  display : block;
  margin : 0;
  padding : 0;
}
form {
  display : block;
  margin : 0;
  padding : 0;
}
frame {
  display : block;
  margin : 0;
  padding : 0;
}
frameset {
  display : block;
  margin : 0;
  padding : 0;
}
h1 {
  display : block;
  font-size : xx-large;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}

For <h1> and the other heading tags to follow, we vary the font-size and line-height, and use font-weight to request a bolder text. Netscape 4 does not support bolder; for that browser, the absolute value bold should be used instead.

h2 {
  display : block;
  font-size : x-large;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}
h3 {
  display : block;
  font-size : large;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}
h4 {
  display : block;
  font-size : medium;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}
h5 {
  display : block;
  font-size : small;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}
h6 {
  display : block;
  font-size : xx-small;
  font-weight: bolder;
  line-height : 1;
  margin : 0;
  padding : 0;
}
head { display : none; }

It is somewhat pedantic to specify that none of the contents of <head> be displayed, as no browser will do that by default, although it is possible in an advanced CSS browser (like the Gecko family) to use CSS to force the contents of <head> to display.

hr {
  border : 1px inset;
  display : block;
  margin : 0;
  padding : 0;
}

For horizontal rules, the border property sets an inset style of border 1px wide. This basically mimics the typical default display of <hr> in browsers.

/*img { display : inline-block; }*/
/*input { display : inline-block; }*/
ins { text-decoration : underline; }
li { display : list-item; }

Again as a default, <li> tags are styled to display as list items. Note that you should never apply styles directly to <li> for Netscape 4. It has a bug where the styles will only be applied to the list item bullet and not to the list item text.

noframes {
  display : block;
  margin : 0;
  padding : 0;
}
/*object { display : inline-block; }*/
ol {
  display : block;
  list-style-type : decimal;
  margin : 0;
  padding : 0;
}

With list-style-type, we declare that <ol> tags (ordered lists/numbered list) will be displayed with each item in the list marked decimal (1., 2., etc.). This is simply another default setting.

p {
  display : block;
  margin : 0;
  padding : 0;
}
pre {
  display : block;
  font-family : monospace;
  margin : 0;
  padding : 0;
  white-space : pre;
}

The white-space : pre rule defines how to treat whitespace in the <pre> tag. As a default, it preserves whitespace in the same fashion as browsers typically do with <pre>.

script { display : none; }
/*select { display : inline-block; }*/
strong { font-weight : bolder; }
sub {
  font-size : smaller;
  vertical-align : sub;
}
sup {
  font-size : smaller;
  vertical-align : super;
}

The sub and super values for vertical-align create the subscript and superscript effect typical of these two tags.

table { display : table; }
tbody { display : table-row-group; }
td { display : table-cell; }
textarea {
  cursor : text;
/*  display : inline-block;*/
}

The cursor property defines what type of cursor should be rendered when the pointer is over the <textarea>, in this case the default vertical text input bar familiar on PC screens.

tfoot { display : table-footer-group; }
th {
  display : table-cell;
  font-weight : bolder;
  text-align : center;
}
thead { display : table-header-group; }
tr { display : table-row; }
ul {
  display : block;
  list-style-type : square;
  margin : 0;
  padding : 0;
}
var { font-style : italic; }

Inheritance and the Cascade

An element on an XHTML page can inherit CSS values from its parent element. For example, one does not typically define a color for every element on a page. Color is usually defined in the <body>. From there other tags inherit it, and only on elements where you want a different color do you specify it in the CSS.

In the case of a property value being defined as a percentage of another element’s value, the percentage itself does not inherit. Instead, the computed value of the percentage inherits. For example, given these CSS rules:

body { font-size : 10px;}
p {font-size : 130%;}

in this XHTML fragment:

<p>Here is a test of <span>font sizes.</span></p>

the <p> tag would be 13px (130% of 10px) in size. The <span> within the <p> does not become 17px (130% of 13px) in size; it simply inherits the computed value of 13px from the <p>.

A CSS property can be assigned the value inherit specifically. This can be used to force inheritance in situations where a value would not normally inherit. For example (not that you probably want to do this):

body { background : url(path_to_an_image_here) no-repeat;
p { background : inherit;}

In this case, whatever background image was assigned to <body> would also repeat in the background of every <p> tag on the page! You can also override inheritance by specifically assigning a value to the property in question on a given element.

Cascading Style Sheets get the “cascading” part of their name from the rules on how stylesheets from different origins interact. Cascade here means that a document can have styles from multiple sources linked to it. The multiple stylesheets have a cascading effect: each one in turn affects the display of the document according to rules that define a hierarchy for which stylesheet rules get priority over competing/conflicting rules from another stylesheet.

Stylesheets can have three origins:

If these different stylesheets have conflicting rules on what styles to set for a given element or elements, the CSS cascade rules define how to “break the tie” and decide what rule to apply. The basic hierarchy, in order of which gets the most weight (that is, takes precedence), is:

  1. User stylesheets
  2. Author stylesheets
  3. Browser default styles

A noteworthy exception is rules tagged as !important, in both author and user stylesheets, to give them more weight than a normally defined rule. However, user !important rules always outweigh author !important rules.

The full set of rules for determining the cascade is:

  1. Take all rules for the element and property that fall in the desired media type.
  2. Sort by weight and origin as discussed above:
    • User styles tagged "!important" (see below)
    • Author styles tagged "!important" (see below)
    • Author styles
    • User styles
    • Browser styles

    Any rule definition in an author or user stylesheet can have !importantplaced after it to indicate that this rule should be given more weight than a normal rule. Example: p {font-size : 16px !important;}.

  3. Sort by specificity . Specificity is used to resolve conflict when two properties in separate rules, which apply to the same element, contradict each other. Rules that are more specific outweigh rules that are less specific. Specificity is calculated to a four-digit number ABCD (higher = more specific), determined as follows:
    • A equals 1 if the rule is in the style attribute of an XHTML element (<p style="font-size : 14px;">. Such rules never have other selectors, so B, C, and D equal zero and the specificity of this type of rule is always 1000.
    • B equals the number of ID attributes in the selector. For example, given the rule #idname li a:hover {}, there is one ID attribute, #idname, so B equals one.
    • C equals the number of non-ID attributes plus the number of pseudo-classes in the selector. In the previous example, #idname li a:hover {} would have a C value of one for the one pseudo-class, :hover.
    • D equals the number of elements in the selector. So #idname li a:hover {} has a D value of two for the two elements li and a. Thus this entire rule has a specificity of 112. (Pseudo-elements are ignored in calculating specificity.)
  4. Finally, if there still is a tie, the order the rules are specified in becomes important. The last rule specified wins. (Rules that are @import-ed in always come before rules in the stylesheet itself.)

Presentation that comes from the XHTML itself, such as a <font> tag or an align attribute is considered as having the same weight as if it had come from the browser’s stylesheet. Note that this is a change in CSS2.1. CSS2 gives presentational XHTML a specificity of zero and assumes the XHTML to be positioned is at the start of the author stylesheet. CSS1 gives presentational XHTML a specificity of 1 and assumes the XHTML to be positioned at the start of the author stylesheet.

User Stylesheets

Browsers today allow the user to pre-define their own stylesheet. A user can set styles that they always want to have, such as having the font set to a certain size. This goes beyond the normal preferences options present in a browser’s interface, such as setting default fonts or whether to use the author’s defined colors. A user stylesheet can contain CSS rules of any sort.

User stylesheets are stored on the user’s computer and can be set as follows in these major browsers:

Absolute and Relative Positioning

Absolute and relative positioning are the major layout tools of CSS.

Absolute Positioning

With absolute positioning, an element is removed completely from the normal flow of the document. Its position is defined by the use of the properties top, bottom, right, and/or left. The element is positioned with respect to its containing block.

Absolute positioning has of late become a tool of choice for creating pages that do not use <table> elements to control layout. A typical example is shown at http://www.accessibleinter.net/, a basic two-column layout. The template relies on absolute positioning to move the left column content (which is actually below the main text of the page in the XHTML code and thus would normally render below the main page copy) up into what becomes the left navigation bar.

Absolute Positioning Example 1

Another layout of note for its not using <table> elements is located at Wired (http://www.wired.com). Again, the left column is placed via CSS when it actually appears near the bottom of the XHTML code.

Absolute Positioning Example 2

Also note fixed positioning, which is the same as absolute except that instead of positioning the element with respect to its containing block, the element is positioned with respect to the viewport (the browser window).

Relative Positioning

Relative positioning sets the position of an element relative to where it would have been statically positioned in the normal XHTML flow. Again, the same four positioning properties are used to define where the element will render. See http://cita.rehab.uiuc.edu/courses/2002-09-REHAB711NC/lec10/slide13.html for a basic example of this technique.

Pseudo-Classes and Pseudo-Elements

Pseudo-classes are defined in the CSS specification as classifying “elements on characteristics other than their name, attributes, or content” so that styles can be applied to them. Generally they are classified in ways outside that which would be possible from their positions in the document, such as styling a <p> tag or all <em> tags within <h1> tags. They are best known for the link pseudo-classes, though there are others.

Link Pseudo-Classes

We saw these two earlier in the annotated stylesheet:

Dynamic Pseudo-Classes

These classes are typically associated with hyperlinks, but can actually apply to any element. At the time of writing, only the Gecko family of browsers and Opera 7 support using pseudo-classes in this fashion. They are dynamic in that an element may move into and out of the pseudo-class depending on the user interaction (a hyperlink is hovered over and takes on the hover rules, then the mouse moves away and the hover rules no longer apply).

Proper Order of Pseudo-Classes on Hyperlinks

Since the dynamic pseudo-classes are not mutually exclusive – an element can be in multiple dynamic states simultaneously – the order the pseudo-classes appear in is important. Recall in the discussion of the cascade that when all else is equal, the last rule defined wins. So the pseudo-classes should be set in a specific order to work correctly.

The traditional school of thought in writing hyperlink pseudo-class styles recommends defining them in this manner:

The :focus pseudo-class has generally been omitted since browser support is poor. It is, however, a useful tool, particularly for helping keyboard users determine where on the page their cursor is (by using the focus styles to draw attention to it). As of this writing, only Netscape 6+ and Internet Explorer 5 for the Mac support :focus.

As browser support improves, however, this system can inadvertently create problems. Since :hover and :active can apply to any element, these rules will give those effects to <a> elements that are target anchors, not hyperlinks, such as:

<a name="theanchor" id="theanchor">I am an anchor.</a>

Less-compliant browsers would not apply any :hover or :active styles to what would otherwise be plain text. So to solve the problem, we would have to write another rule for those <a> elements. Or, the rules can be written in this revised format:

In this method, :hover and :active, as well as :focus, can only match hyperlinks since they are tied to :link instead of to an <a> element. This has the advantage of being forward-compatible with XHTML 2.0 as well, since XHTML 2.0 allows any element to be a hyperlink, not just an <a> element. Even :focus has found a home in the rules as well – its odd location is to circumvent browser bugs in Internet Explorer 5.0/PC. The only disadvantages noted at the time of writing come in two browsers. Internet Explorer 3 will apply the :focus styles to the body of the page’s text. Opera 6/PC and 5/Mac will not apply any :hover or :active styles, as the browser has a bug where it does not understand this combining of pseudo-classes.

(Note: This guide to ordering pseudo-classes is adapted from an original article by the author which first appeared on evolt.org, http://www.evolt.org/).

Other Pseudo-Classes

:lang matches  elements that are in a particular language. Language is defined by the lang attribute in XHTML, and by the xml:lang attribute in XML. So for example:

span:lang(fr)

would match against any <span> tag that had a lang attribute equal to fr (French).

Different languages have different conventions for such things as quotation marks, when to bold/italic, etc. With this pseudo-class one stylesheet can contain different rules for different languages, rather than having separate sheets for each language.

:first-child matches  any element that is the first child of the parent element.

Pseudo-Elements

Pseudo-elements “create abstractions about the document tree beyond those specified by the document language” (http://www.w3.org/TR/CSS21/selector.html#x22). They enable the developer to apply styles to abstract structures that are otherwise indefinable.

Revealing The accesskey Via Pseudo-Elements

XHTML has the accesskey attribute, where a key can be assigned to a hyperlink or a form field. This key, in combination with a modifier key on the keyboard (typically the Ctrl key in Windows or the Command key on a Mac) will enable the browser to jump into that form field or activate the hyperlink.

In the typical browser, though, the accesskey is invisible unless the page specifically lists or shows what accesskeys exist and what they’re assigned to. With a little help from pseudo-elements, though, you can have the page’s CSS display this information.

The CSS rule looks like this:

  *[accesskey]:after {
    content : " <" attr(accesskey) ">";
  }

* is the universal selector. It means this rule applies to any element. [accesskey] means “if the accesskey attribute exists”. So the rule so far is “For any element, if the accesskey attribute has been defined….:after means that the generated content will appear after the element. The content property defines what the generated content will be. First we print a space and a <, then attr(accesskey) means “print the value of the accesskey attribute for this element”. We then close by printing >.

So for an example, this hyperlink:

<a href="somewhere.html" accesskey="s">A link to somewhere</a>

would look like this in the browser with the CSS applied:

A link to somewhere <s>

This does require some strong browser support. Currently this technique would only work in the Gecko browser family, and in Opera 7. Other browsers would just ignore the CSS and do nothing. But since it does degrade safely in browsers that don’t support it, it’s a useful trick .

CSS Property Reference

Key
property-name Description of shorthand property
property-value Description of default value.
property-value Description of other possible value. Text in <angle brackets> indicates a user-specified value.
[property-name] Property that can be defined within the above shorthand property.
property-value Description of default value.
property-value Description of other possible value. Text in <angle brackets> indicates a user-specified value.

All properties take the value of “inherit”, meaning , “inherit the value of the parent element”. Many values are set as a given amount of a specific unit of length, or as a percentage. See the Choosing the right unit of measurement section that follows for more details on the types of units available .

background Shorthand for the background properties .
[background-color] Set background color.
transparent The background of the parent element shows through
<color name> The background color is set to the named color
<RGB code> The background color is set to the specified color
[background-image] Sets a background image.
none No background image
<URL> Background image taken from the supplied URL.
[background-repeat] Whether/how a background should tile.
repeat Tiles the background horizontally and vertically
repeat-x Tiles horizontally (on the x-axis)
repeat-y Tiles vertically (on the y-axis)
no-repeat No repeating/tiling
[background-attachment] Does background image scroll?
scroll Image scrolls as the document is scrolled
fixed Image is fixed in place
[background-position] Position of background image right and down the element box.You can combine two of the keywords, as in top left or center right
0% 0% is the default value
top Background is positioned at the top
center Background is positioned at the center
bottom Background is positioned at the bottom
left Background is positioned at the left
right Background is positioned at the right
<length unit> Background is <length unit> from top, can specify as em, px, or pt.
<percentage> <percentage> 0% 0% is top-left corner, 100% 100% is bottom-right corner


border Shorthand for the border properties
[border-width] Width of all four borders around an element.
medium Border is of medium width
thin Border is thin
thick Border is thick
<length unit> Border will be of <length unit> width, in px.
[border-style] Styling of all four borders around an element
none No styling applied
hidden Border is hidden
dotted Border is dotted
dashed Border is dashed
solid Border is solid
double Border is double
groove Border is a groove
ridge Border is a ridge
inset Border is inset to the boundary
outset Border is outset to the boundary
[border-collapse]

Selects table-cell border model to use.
Note: the default was “collapse” in CSS2. It was changed in CSS2.1 since most browsers use “separate” or have built-in behavior that more resembles “separate”.

separate Use the separate border model (one continuous border around tables, table cells, etc.)
collapse Use the collapsing border model (borders around cells, rows, columns, etc. can be controlled as with the rules attribute of the XHTML <table> tag)
[border-color] Colors of all four borders around an element.Default value is the color set for each sideNote: In CSS2 “color” was used instead of “border-top-color”
<color name> Border is set to specified <color name>
<RGB code> Border is set to specified <RGB code>
transparent Allows underlying color through
[border-spacing] Distance between adjacent table cell borders.Value is set as a length unit
0 No space between adjacent cell borders
<length unit> Adjacent cell borders <length unit> spaced, in px.


border-top,
border-right,
border-bottom,
border-left
Shorthand for width, style, and color of borders  
[border-top-color],
[border-right-color],
[border-bottom-color],
[border-left-color]
Colors for each border. Set individually as [border-color] above. Default value is the color set for each side
[border-top-style],
[border-right-style],
[border-bottom-style],
[border-left-style]
Styles for each border. Set individually as [border-style] above
[border-top-width],
[border-right-width],
[border-bottom-width],
[border-left-width]
Width of each border. Set individually as [border-width] above.


bottom Positioning of an element .
auto Position is calculated by browser’s default
<length unit> The element is the specified length from the bottom, in px
<percentage> The element is the specified percentage of its parent element from the bottom
top Positioning of an element. Set as [bottom] above
left Positioning of an element. Set as [bottom] above
right Positioning of an element. Set as [bottom] above


caption-side Position of a table caption Note: CSS2 also has the values of “left” and “right”, which have been removed in CSS2.1.
top Caption is above the table box
bottom Caption is below the table box

clear Which sides of element box should clear (not be adjacent to) an earlier float? (equivalent to <br clear="…" /> in XHTML)
none No attempt to clear a float
left Render this box clear of left-floated boxes
right Render this box clear of right-floated boxes
both Render this box clear of all floated boxes

clip What part of an absolutely positioned box should be visible?
auto Visible region is calculated as the normal size and location of the element box
rect The syntaxrect([top], [right], [bottom], [left] defines how much to offset the clipped region from the normal visible box borders.

color Foreground color of textual content
  Default value is browser-dependent
<color name> Text is set to specified <color name>
<RGB code> Text is set to specified <RGB code>

content Used to generate content (render content that is not in the XHTML code) with the :before and :after pseudo-elements .Note: CSS2 had the additional values of [counter] and [uri],which have been dropped in CSS2.1.
  Default value is an empty string
string A string of text
attr[X] Returns the value of attribute X for whatever selector the CSS rule applies to
open-quote, close-quote Returns an appropriate set of quotation marks
no-open-quote, no-close-quote Returns an empty string for quotation marks

cursor Define what type of cursor to display  Note: “progress” is new in CSS2.1 and does not exist in CSS2. Also note that the value [uri] existed in CSS2 and has been dropped in CSS2.1.
auto  Browser picks the appropriate cursor
crosshair A “+” shaped cursor
default OS/platform default, typically an arrow
pointer Arrow that indicates a hyperlink below the cursor
move Shows that some object is to be moved
e-resize,
ne-resize,
n-resize,
nw-resize,
w-resize,
sw-resize,
s-resize,
se-resize
Shows that an edge of an object can be moved
text The text below the cursor is selectable, usually rendered as an I-bar
wait Hourglass or watch symbol that a program is doing something and the user should wait
progress Indicator that the program is doing something but that the user can still interact. The indicator is often a “spinning beach ball” symbol, or an arrow with an hourglass.
help Some sort of help is available for the object under the cursor. Can be a “?” symbol or a “help balloon”

direction  Direction of the flow of text
ltr Text runs left to right
rtl Text runs right to left

display Defines how an element will display
inline Element displays inline Note: while the default is inline, browser stylesheets will change the default of many elements (such as paragraphs) to block
block Element displays as block-level
inline-block Element internally acts as block-level, but flows in the document as an inline box Note: This value did not exist in CSS2. CSS2 had the value “compact”, which has been dropped in CSS2.1. The value of “marker” has also been dropped in CSS2.1.
list-item Element displays like a list item, generating an overall block box and a list-item inline box
none Element is not displayed on the page
run-in Can be inline or block, depending on the context
table,
inline-table,
table-row-group,
table-column,
table-column-group,
table-header-group,
table-footer-group,
table-row,
table-cell,
table-caption
Element displays as the appropriate type of table element

empty-cells Whether or not borders and background should be rendered for empty table cells
show Render borders and backgrounds
hide Do not render borders and backgrounds

float Whether and how a box should be floated
none Box does not float
left Box floats left, content flows to its right
right Box floats right, content flows to its left

font Shorthand for font properties
caption Font for captioned controls (such as form buttons)
icon Font used on icon labels
menu Font used in menus (such as a drop-down menu)
message-box Font used in dialog boxes
small-caption Font used for labeling small controls
status-bar Font used for window status bar text
[font-style] Font face
normal Normal face for the font
italic Italic face
oblique Oblique face
[font-variant] Font variation to apply
normal Display the font normally
small-caps Render a small-caps font
[font-weight] Boldness to apply to a font
normal No boldness (equivalent to 400 on the following scale)
[100, 200, 300, 400, 500, 600, 700, 800, 900] Sequence/scale of font boldness to apply
bold   Bold (equal to 700 on the above scale)
bolder Bolder than the parent element (one step up the scale)
lighter   Less bold than the parent element (one step down the scale)
[font-size] Sizing of fonts
medium Roughly equivalent to <font size="3">
xx-small  
x-small  
small  
large  
x-large  
xx-large  
larger Makes the font one size larger than its parent
smaller Makes the font one size smaller than its parent
<length unit> Specify font size in px, pt, or em
<percentage> Makes the font a percentage of its parent
[font-family] Specifies a font
  The default is browser-dependent
<family-name> The name of a particular font (such as Verdana)
<generic-family> A generic font family name (serif, sans-serif, cursive, fantasy, monospace)
[line-height] Leading between lines of text
normal Browser chooses a reasonable value based on the font
<length unit> Line will be the specified height in px
<number> Line height will be the font size of the element multiplied by the supplied number
<percentage> Line height will be a percentage of the font size of the element

height Height of an element
auto  Height is automatically determined by the browser, based on the content of the element and the surrounding elements
<length unit> Element is the specified height, in px or em
<percentage> Element is a percentage of the height of its parent
width Width of an element. Set as [height] above

letter-spacing Spacing between characters of text
normal Standard spacing for the given font
<length unit> Characters are spaced the specified distance, in px, or em, in addition to the standard spacing

list-style Shorthand for the list-style properties
[list-style-type] Appearance of the list item bullet/marker
disc Marker is a disc
circle Marker is a circle
square Marker is a square
decimal Marker is numeric, starting at 1
decimal-leading-zero Numeric with leading zero (01, 02, etc.)
lower-roman,
upper-roman
Lowercase Roman numerals (i, ii, iii)
Uppercase Roman numerals (I, II, III)
lower-greek Lowercase classical Greek: (α, β, γ)
lower-alpha,
lower-latin 
Lowercase ASCII letters
upper-alpha,
upper-latin 
Uppercase ASCII letters
hebrew Traditional Hebrew numbering
armenian Traditional Armenian numbering
georgian  Traditional Georgian numbering
cjk-ideographic Plain ideographic numbers
hiragana  a, i, u, e, o, ka, ki, etc.
katakana A, I, U, E, O, KA, KI, etc.
hiragana-iroha i, ro, ha, ni, ho, he, to, etc.
katakana-iroha I, RO, HA, NI, HO, HE, TO, etc.
none No marker is displayed
[list-style-position]  Location of bullet in the overall block box
outside Bullet falls outside the box
inside Bullet falls inside the box
[list-style-image]  Image to use as the “bullet” for list items
none No image for list item bullets
<URI> URI to the image to be used

margin Shorthand for the margin properties
[margin-right] Right margin width of most elements
0 No margin
auto Margin is set as browser default
<length unit> Margin is set to specified length, in px or em
<percentage> Margin is set to specified percentage of parent element’s margin
[margin-left] Left margin width of most elements, set as [margin-right] above
[margin-top] Top margin width of most elements, set as [margin-right] above
[margin-bottom] Bottom margin width of most elements, set as [margin-right] above

max-height Maximum height on all but non-replaced inline elements and table elements
0 No limit on the element’s height
<length unit> Element is limited to specified height, in px or em
<percentage> Element is limited to specified percentage of parent element’s height
max-width Maximum width on all but non-replaced inline elements and table elements. Set as [max-height] above.

min-height Minimum height on most elements
0 No minimum to the element’s height
<length unit> Element is limited to specified height, in px or em, as a minimum
<percentage> Element is limited to specified percentage of parent element’s height, as a minimum
min-width Minimum width on most elements, set as [min-height] above

outline Shorthand for the outline properties
[outline-color] Color of outlines (the lines that appear around a hyperlink if you tab-keyboard the cursor onto it)
invert Performs a “color inversion” on the pixels on the screen
<color name> Outline color is set to specified color name
<RGB code> Outline color is set to specified RGB code
[outline-style] Style of the outline
none No outline
dotted Outline is dotted
dashed Outline is dashed
solid Outline is solid
double Outline is double
groove Outline is a groove
ridge Outline is a ridge
inset Outline is inset to the boundary
outset Outline is outset to the boundary
[outline-width] Width of the outline
medium Outline is of medium width
thin Outline is thin
thick Outline is thick
<length unit> Outline is the specified width, in px

overflow How to display content that flows outside the confines of the element’s box
visible Render the overflow content
hidden Hide the overflow content
scroll Provide scrollbars for viewing overflow content, regardless of whether an overflow has actually occurred or not
auto  Browser-dependent response

padding Shorthand for the padding properties
[padding-top]'
[padding-right],
[padding-bottom],
[padding-left]
Padding around each of the four sides of an element
0 No padding
<length unit> Element has specified padding, in px or em
<percentage> Element has specified percentage of parent element’s padding

page break after Page break rules for after an element box
auto Page break is neither forced nor forbidden
always Always page break
avoid Avoid a page break
left Force one or two page breaks as required to make the next page a “left” page
right Force one or two page breaks as required to make the next page a “right” page
page-break-before Page break rules for before an element box. Set as page-break-after above.
page-break-inside Page break rules inside an element box. Set as page-break-after above.

position Positioning of an element box
static Box is laid out by normal positioning rules
relative Box will be offset by a given amount relative to its normal position
absolute Box is positioned by top, right, bottom, and left properties
fixed  As absolute, except that the box is fixed in position

quotes Designates quotation marks to be used
  The default value is locale- and browser-dependent
none  The content property open-quote and close-quote values will produce no quote marks
<string string> The quote symbols specified in string will be used. Multiple strings for quotes within quotes can be specified

table-layout How to lay out table contents in table and inline-table elements
auto Use an automatic table layout
fixed Use a fixed layout independent of the actual contents of the table cells

text-align  How to align block content
  The default value depends on browser and on normal flow of text (left to right or right to left)
left  Left-justify the text
right Right-justify the text
center Center the text
justify Justify the text
<string> Applies only to table cells; sets a string on which cells will align

text-decoration  Decoration to apply to text
none No decoration
underline Text is underlined
overline Text has a line above it
line-through Text has a line through its middle, horizontally
blink Text blinks on and off

text-indent  How much to indent the first line of a block of text
0 No indent
<length unit> Indent measured as a length unit
<percentage> Indent measured as a percentage

text-transform  Capitalization transformation effect
none No special effect
capitalize Capitalize the first character of each word
uppercase Uppercase all characters
lowercase Lowercase all characters

unicode-bidi  Part of defining how text is properly bi-directional rendered
normal No special rules/embedding apply
embed  For inline-level elements, a new level of embedded is opened in the bi-directional algorithm
bidi-override Depending on the type of element, creates an override of the normal algorithm

vertical-align Vertical positioning rules, relative to parent element . Note that these rules are not meant to be used to “center” an element between the top/bottom of the page, though users often try to do that)
baseline Baseline aligned with baseline of parent box
sub  Lowers baseline to create “subscript” effect. Doesn't change font size.
super Raises baseline to create “superscript” effect. Doesn't change font size.
top  Align top with the top of the line box.
text-top  Align top with the top of parent element’s font.
middle Align vertical midpoint with the baseline of parent plus half the x-height of parent.
bottom Align bottom with the bottom of the line box.
text-bottom  Align bottom with the bottom of parent element’s font.
<length unit>,
<percentage>
Positive numbers raise the positioning, negative lower it.

visibility Whether or not a box’s element is rendered
inherit Box inherits its visibility from its parent element
visible Box is visible
hidden Box is hidden Note: a hidden box still affects the overall page layout (it takes up space on the page though the content is hidden from view, other elements will interact with it in terms of float, applying margin, etc.).
collapse  Causes table rows or columns to be removed; in non-table situations, the same as hidden

white-space  How to handle whitespace within an element
normal Browser collapses whitespace sequences, and line breaks as needed
pre No collapsing of whitespace sequences, line breaks at new lines in the code
nowrap As normal, but line breaks are suppressed

word-spacing  Space between words
normal Normal as defined by the font and/or the browser
<length unit> In addition to the default, specified in px, em

z-index  Stacking of positioned boxes (which element box should be on top of the others, when boxes overlap)
auto Stacking level as from the parent
<number> A number that equals the stack level (highest number is at the top of the stack, lower numbers follow in order)

The following properties are in CSS2, but have been dropped from CSS2.1: counter-increment, counter-reset, font-size-adjust, font-stretch, marker-offset, marks, orphans, size, text-shadow, and widows.

Additionally, all the aural stylesheet properties (stylesheets for speech synthesizers and speech browsers) have been removed from CSS2.1, since in CSS2.1 aural stylesheets are not a part of the normative specification (they still exist as an informative appendix to the specification): azimuth, cue, cue-after, cue-before, elevation, pause, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, and volume.

Choosing the Right Unit of Measurement

CSS offers a number of ways to define what units of measure your CSS properties will be in. Units of length can be absolute in size, or relative to some other property.

Absolute lengths include:

Relative units include:

Also relative is defining the measurement of a given property as a percentage of another value.

Note: since aural stylesheets are not part of the normative CSS2.1 specification as they were in CSS2, the following aural units are also no longer normative in CSS2.1: deg (degrees), grad (grads), rad (radians), ms (milliseconds), s (seconds), Hz (Hertz), and kHz (kilo Hertz).

Choosing the correct means of measurement can be crucial, particularly when defining font sizes. A poor choice can impact on the accessibility and usability of the web page in question.

Absolute units are generally of least value, with the exception of points. Points are a unit of measurement in print and thus are perfectly acceptable and suited for print stylesheets. Points should not be used for a screen stylesheet, as they will render at varying sizes depending on the user’s platform and screen resolution. Often a font in points that simply looks small on a Windows machine will become illegible on a Macintosh.

Relative units are better to use, but browser bugs make most of them (including percentages) useless unless you use techniques to hide CSS from specific browsers (see the earlier section in this chapter). Netscape 4 has problems with ems, exs, and percentages. Internet Explorer 3 renders ems as pixels, and has issues with percentages. Without techniques to hide CSS from certain browsers, only the pixel is considered a safe cross-browser, cross-platform unit. Its major drawback is that Internet Explorer on the PC will not allow you to resize fonts measured in pixels, as other browsers will. This is a major accessibility issue as users lose the ability to resize text to their comfort level if the pixel size is too small.

Also note that font size can be defined using keywords (xx-small, x-small, small, medium, large, x-large, xx-large). Again, browser bugs make this method useless unless you hide the CSS from browsers that have problems with it. But if you are doing that, this method can be one of the best ways to define font sizes. For more on this technique, “Using Relative Font Sizes” on Dive into Accessibility at http://diveintoaccessibility.org/day_26_using_relative_font_sizes.html is recommended reading .

CSS Selector Reference

Selector Definition Example
* Universal selector, matches any element *[lang] { font-style : italic; }
X Matches any element of type X p { font-size : 14px; }
X Y Matches any element Y that is a descendant of an element X h1 strong { color : red; }
X>Y Matches any element Y that is a child of an element X html>body { font-size : medium; }
X:first-child Matches any element X that is the first child of its parent element p:first-child {
font-weight : bold; }
X:link, X:visited Matches element X if X is an unvisited or visited hyperlink a:link {
text-decoration : underline; }
X:active, X:hover, X:focus Matches element X during certain user actions (X is active, hovered over, or has the focus) a:hover {
text-decoration : none; }
X:lang(y) Matches element X if X is in language Y abbr:lang(fr) {
font-style : italic; }
X+Y Matches any element Y that is immediately preceded by an element X h1+p { margin-top : 0;}
X[attribute] Matches any element X that has the named attribute set (regardless of the attribute’s value) acronym[title] {
cursor : help; }
X[attribute="y"] Matches any element X that has the named attribute set and equal to y in value a[accesskey="0"] {
font-weight : bold; }
X[attribute~="y"] Matches any element X with the named attribute, where the value of the attribute is a list of space-separated values, one of which equals y p[class~="summary"] {
color : green; }
X[attribute|="y" Matches any element X with the named attribute that has a hyphen-separated list of values beginning with y label[for|="required"] {
font-weight : bold; }
X.y Matches any element X with a class attribute that is a list of space-separated values, one of which equals y ul.mainlist {
list-style-type : disc; }
X#y Matches any element X with an id attribute that equals y. p#intro { line-height : 1.3; }

Summary

CSS is an integral piece of today’s web development. With it, the classic separation of content from presentation is possible. While the latest browsers have strong CSS1 support, CSS2 support is not quite complete. Older browsers remaining on the market in substantial numbers that bugs even in their CSS1 support. This makes the techniques of hiding advanced CSS from older browsers an important part of CSS development.

Another integral part of CSS development is its power in creating accessible web pages. CSS’s ability to handle presentation, coupled with the user’s ability to write their own user stylesheet and introduce it into the cascade, give the end-user strong tools in controlling a web page’s presentation to suit his/her needs. As with any tool, there are right and wrong ways to use CSS to enhance usability and accessibility.

CSS offers a vast array of tools to the front-end developer. This broad range is a must-have for today’s web development.

Other References

The most obvious book to go to next is Cascading Style Sheets: Separating Content from Presentation, from glasshaus, ISBN 1-904151-04-3. As with all the other chapters in the book, a wide selection of links are available from our web site.