BUY THIS BOOK

Safari Books Online

What is this?

Looking to Reprint this content?


Cascading Style Sheets: The Definitive Guide
Cascading Style Sheets: The Definitive Guide, Second Edition By Eric A. Meyer
March 2004
Pages: 528

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: CSS and Documents
Cascading Style Sheets (CSS) are a powerful way to affect the presentation of a document or a collection of documents. Obviously, without a document of some sort, CSS is basically useless since it would have no content to present. Of course, the definition of "document" is extremely broad. For example, Mozilla and related browsers use CSS to affect the presentation of the browser chrome itself. Still, without the content of the chrome—buttons, address inputs, dialog boxes, windows, and so on—there would be no need for CSS (or any other presentational information).
Back in the dimly remembered, early years of the Web (1990-1993), HTML was a fairly lean language. It was composed almost entirely of structural elements that were useful for describing things like paragraphs, hyperlinks, lists, and headings. It had nothing even remotely approaching tables, frames, or the complex markup we assume is a necessary part of creating web pages. The general idea was that HTML would be a structural markup language, used to describe the various parts of a document. Very little was said about how those parts should be displayed. The language wasn't concerned with appearance. It was just a clean little markup scheme.
Then came Mosaic.
Suddenly, the power of the World Wide Web was obvious to almost anyone who spent more than 10 minutes playing with it. Jumping from one document to another was no harder than pointing the mouse cursor at a specially colored bit of text, or even an image, and clicking the mouse button. Even better, text and images could be displayed together, and all you needed to create a page was a plain-text editor. It was free, it was open, and it was cool.
Web sites began to spring up everywhere. There were personal journals, university sites, corporate sites, and more. As the number of sites increased, so did the demand for new HTML elements that would each perform a specific function. Authors started demanding that they be able to make text boldfaced, or italicized.
At the time, HTML wasn't equipped to handle those sorts of desires. You could declare a bit of text to be emphasized, but that wasn't necessarily the same as being italicized—it could be boldfaced instead, or even normal text with a different color, depending on the user's browser and her preferences. There was nothing to ensure that what the author created was what the reader would see.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Web's Fall from Grace
Back in the dimly remembered, early years of the Web (1990-1993), HTML was a fairly lean language. It was composed almost entirely of structural elements that were useful for describing things like paragraphs, hyperlinks, lists, and headings. It had nothing even remotely approaching tables, frames, or the complex markup we assume is a necessary part of creating web pages. The general idea was that HTML would be a structural markup language, used to describe the various parts of a document. Very little was said about how those parts should be displayed. The language wasn't concerned with appearance. It was just a clean little markup scheme.
Then came Mosaic.
Suddenly, the power of the World Wide Web was obvious to almost anyone who spent more than 10 minutes playing with it. Jumping from one document to another was no harder than pointing the mouse cursor at a specially colored bit of text, or even an image, and clicking the mouse button. Even better, text and images could be displayed together, and all you needed to create a page was a plain-text editor. It was free, it was open, and it was cool.
Web sites began to spring up everywhere. There were personal journals, university sites, corporate sites, and more. As the number of sites increased, so did the demand for new HTML elements that would each perform a specific function. Authors started demanding that they be able to make text boldfaced, or italicized.
At the time, HTML wasn't equipped to handle those sorts of desires. You could declare a bit of text to be emphasized, but that wasn't necessarily the same as being italicized—it could be boldfaced instead, or even normal text with a different color, depending on the user's browser and her preferences. There was nothing to ensure that what the author created was what the reader would see.
As a result of these pressures, markup elements like <B> and <I> started to creep into the language. Suddenly, a structural language started to become presentational.
Years later, we have inherited the problems of this haphazard process. Large parts of HTML 3.2 and HTML 4.0, for example, were devoted to presentational considerations. The ability to color and size text through the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
CSS to the Rescue
Of course, the problem of polluting HTML with presentational markup was not lost on the World Wide Web Consortium (W3C), which began searching for a quick solution. In 1995, the consortium started publicizing a work-in-progress called CSS. By 1996, it had become a full Recommendation, with the same weight as HTML itself. Here's why.
In the first place, CSS allows for much richer document appearances than HTML ever allowed, even at the height of its presentational fervor. CSS lets you set colors on text and in the background of any element; permits the creation of borders around any element, as well as the increase or decrease of the space around them; lets you change the way text is capitalized, decorated (e.g., underlining), spaced, and even whether it is displayed at all; and allows you to accomplish many other effects.
Take, for example, the first (and main) heading on a page, which is usually the title of the page itself. The proper markup is:
<h1>Leaping Above The Water</h1>
Now, suppose you want this title to be dark red, use a certain font, be italicized and underlined, and have a yellow background. To do all of that with HTML, you'd have to put the h1 into a table and load it up with a ton of other elements like font and U. With CSS, all you need is one rule:
h1 {color: maroon; font: italic 2em Times, serif; text-decoration: underline; 
      background: yellow;}
That's it. As you can see, everything you did in HTML can be done in CSS. There's no need to confine yourself to only those things HTML can do, however:
h1 {color: maroon; font: italic 2em Times, serif; text-decoration: underline; 
      background: yellow url(titlebg.png) repeat-x; 
      border: 1px solid red; margin-bottom: 0; padding: 5px;}
You now have an image in the background of the h1 that is only repeated horizontally, and a border around it, which is separated from the text by at least five pixels. You've also removed the margin (blank space) from the bottom of the element. These are feats that HTML can't even come close to matching—and that's just a taste of what CSS can do.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Elements
Elements are the basis of CSS display. In HTML, the most common elements are easily recognizable, such as p, table, span, a, and div. In XML languages, the elements are defined by the language's Document Type Definition (DTD). Every single element in a document plays a part in its presentation. In CSS terms, at least as of CSS2.1, that means each element generates a box that contains the element's content.
Although CSS depends on elements, not all elements are created equally. For example, images and paragraphs are not the same type of element, nor are span and div. In CSS, elements generally take two forms: replaced and nonreplaced. The two types are explored in detail in Chapter 7, which covers the particulars of the box model, but I'll address them briefly here.

Section 1.3.1.1: Replaced elements

Replaced elements are those where the element's content is replaced by something that is not directly represented by document content. The most familiar XHTML example is the img element, which is replaced by an image file external to the document itself. In fact, img has no actual content, as you can see by considering a simple example:
<img src="howdy.gif" />
This code snippet contains no actual content—only an element name and an attribute. The element presents nothing unless you point it to some external content (in this case, an image specified by the src attribute). The input element is also replaced by a radio button, checkbox, or text input box, depending on its type. Replaced elements also generate boxes in their display.

Section 1.3.1.2: Nonreplaced elements

The majority of HTML and XHTML elements are nonreplaced elements. This means their content is presented by the user agent (generally a browser) inside a box generated by the element itself. For example, <span>hi there</span> is a nonreplaced element, and the text "hi there" will be displayed by the user agent. This is true of paragraphs, headings, table cells, lists, and almost everything else in XHTML.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Bringing CSS and XHTML Together
I've mentioned that HTML and XHTML documents have an inherent structure, and that's a point worth repeating. In fact, that's part of the problem with web pages of old: too many of us forgot that documents are supposed to have an internal structure, which is altogether different than a visual structure. In our rush to create the coolest-looking pages on the Web, we bent, warped, and generally ignored the idea that pages should contain information that has some structural meaning.
That structure is an inherent part of the relationship between XHTML and CSS; without the structure, there couldn't be a relationship at all. In order to understand it better, let's look at an example XHTML document and break it down by pieces:
<html>
<head>
<title>Eric's World of Waffles</title>
<link rel="stylesheet" type="text/css" href="sheet1.css" media="all" />
<style type="text/css">
@import url(sheet2.css);
h1 {color: maroon;}
body {background: yellow;}
/* These are my styles! Yay! */
</style>
</head>
<body>
<h1>Waffles!</h1>
<p style="color: gray;">The most wonderful of all breakfast foods is  
the waffle--a ridged and cratered slab of home-cooked, fluffy goodness 
that makes every child's heart soar with joy. And they're so easy to make!  
Just a simple waffle-maker and some batter, and you're ready for a morning 
of aromatic ecstasy!
</p>
</body>
</html>
The above markup is shown in Figure 1-4.
Figure 1-4: A simple document
Now, let's examine the various ways this document connects to CSS.
First, consider the use of the link tag:
<link rel="stylesheet" type="text/css" href="sheet1.css" media="all" />
The link tag is a little-regarded but nonetheless perfectly valid tag that has been hanging around the HTML specification for years just waiting to be put to good use. Its basic purpose is to allow HTML authors to associate other documents with the document containing the link tag. CSS uses it to link style sheets to the document; in Figure 1-5, a style sheet called sheet1.cs s is linked to the document.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Summary
With CSS, it is possible to completely change the way elements are presented by a user agent. This can be done at a basic level with the display property, and in a different way by associating style sheets with a document. The user will never know whether this is done via an external or embedded style sheet, or even with an inline style. The real importance of external style sheets is the way in which they allow authors to put all of a site's presentation information in one place, and point all of the documents to that place. This not only makes site updates and maintenance a breeze, but it helps to save bandwidth since all of the presentation is removed from documents.
To make the most of the power of CSS, authors need to know how to associate a set of styles with the elements in a document. In order to fully understand how CSS can do all of this, authors need a firm grasp of the way CSS selects pieces of a document for styling, which is the subject of the next chapter.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Selectors
One of the primary advantages of CSS—particularly to designers—is its ability to easily apply a set of styles to all elements of the same type. Unimpressed? Consider this: by editing a single line of CSS, you can change the colors of all your headings. Don't like the blue you're using? Change that one line of code, and they can all be purple, yellow, maroon, or any other color you desire. That lets you, the designer, focus on design, rather than grunt work. The next time you're in a meeting and someone wants to see headings with a different shade of green, just edit your style and hit Reload. Voilà! The results are accomplished in seconds and are there for everyone to see.
Of course, CSS can't solve all your problems—you can't use it to change the color of your GIFs, for example—but it can make some global changes much easier. So let's begin with selectors and structure.
As I've stated, a central feature of CSS is its ability to apply certain rules to an entire set of element types in a document. For example, let's say that you want to make the text of all h2 elements appear gray. Using old-school HTML, you'd have to do this by inserting <FONT COLOR="gray">...</FONT> tags in all your h2 elements:
<h2><font color="gray">This is h2 text</font></h2>
Obviously, this is a tedious process if your document contains a lot of h2 elements. Worse, if you later decide that you want all those h2s to be green instead of gray, you'd have to start the manual tagging all over again.
CSS allows you to create rules that are simple to change, edit, and apply to all the text elements you define (the next section will explain how these rules work). For example, simply write this rule once to make all your h2 elements gray:
h2 {color: gray;}
If you want to change all h2 text to another color—for example, silver—simply alter the rule:
h2 {color: silver;}
In order to understand the concept of rules in more detail, let's break down the structure.
Each rule has two fundamental parts, the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Basic Rules
As I've stated, a central feature of CSS is its ability to apply certain rules to an entire set of element types in a document. For example, let's say that you want to make the text of all h2 elements appear gray. Using old-school HTML, you'd have to do this by inserting <FONT COLOR="gray">...</FONT> tags in all your h2 elements:
<h2><font color="gray">This is h2 text</font></h2>
Obviously, this is a tedious process if your document contains a lot of h2 elements. Worse, if you later decide that you want all those h2s to be green instead of gray, you'd have to start the manual tagging all over again.
CSS allows you to create rules that are simple to change, edit, and apply to all the text elements you define (the next section will explain how these rules work). For example, simply write this rule once to make all your h2 elements gray:
h2 {color: gray;}
If you want to change all h2 text to another color—for example, silver—simply alter the rule:
h2 {color: silver;}
In order to understand the concept of rules in more detail, let's break down the structure.
Each rule has two fundamental parts, the selector and the declaration block. The declaration block is composed of one or more declarations, and each declaration is a pairing of a property and a value. Every style sheet is made up of a series of rules.Figure 2-1 shows the parts of a rule.
Figure 2-1: The structure of a rule
The selector, shown on the left side of the rule, defines which piece of the document will be affected. In Figure 2-1, h1 elements are selected. If the selector were p, then all p (paragraph) elements would be selected.
The right side of the rule contains the declaration block, which is made up of one or more declarations. Each declaration is a combination of a CSS property and a value of that property. In Figure 2-1, the declaration block contains two declarations. The first states that this rule will cause parts of the document to have a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Grouping
So far, we've learned fairly simple techniques for applying a single style to a single selector. But what if you want the same style to apply to multiple elements? If that's the case, you'll want to use more than one selector or apply more than one style to an element or group of elements.
Let's say you want h2 elements and paragraphs to have gray text. The easiest way to accomplish this is to use the following declaration:
h2, p {color: gray;}
By placing the h2 and p selectors on the left side of the rule and separating them with a comma, you've defined a rule where the style on the right (color: gray;) applies to the elements referenced by both selectors. The comma tells the browser that there are two different selectors involved in the rule. Leaving out the comma would give the rule a completely different meaning, which we'll explore later in Section 2.5.2.
There are really no limits on how many selectors you can group together. For example, if you want to display a large number of elements in gray, you might use something like the following rule:
body, table, th, td, h1, h2, h3, h4, p, pre, strong, em, b, i {color: gray;}
Grouping allows an author to drastically compact certain types of style assignments, which makes for a shorter style sheet. The following alternatives produce exactly the same result, but it's pretty obvious which one is easier to type:
h1 {color: purple;}
h2 {color: purple;}
h3 {color: purple;}
h4 {color: purple;}
h5 {color: purple;}
h6 {color: purple;}

h1, h2, h3, h4, h5, h6 {color: purple;}
Grouping allows for some interesting choices. For example, all of the groups of rules in the following example are equivalent—each merely shows a different way of grouping both selectors and declarations:
/* group 1 */
h1 {color: silver; background: white;}
h2 {color: silver; background: gray;}
h3 {color: white; background: gray;}
h4 {color: silver; background: white;}
b {color: gray; background: white;}

/* group 2 */
h1, h2, h4 {color: silver;}
h2, h3 {background: gray;}
h1, h4, b {background: white;}
h3 {color: white;}
b {color: gray;}

/* group 3 */
h1, h4 {color: silver; background: white;}
h2 {color: silver;}
h3 {color: white;}
h2, h3 {background: gray;}
b {color: gray; background: white;}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Class and ID Selectors
So far, we've been grouping selectors and declarations together in a variety of ways, but the selectors we've been using are still simple ones. The selectors we've used refer only to document elements; they're fine up to a point, but there are times when you need something a little more specialized.
In addition to raw document elements, there are two other types of selectors: class selectors and ID selectors, which let you assign styles in a way that is independent of document elements. These selectors can be used on their own or in conjunction with element selectors. However, they work only if you've marked up your document appropriately, so using them generally involves a little forethought and planning.
For example, say you're drafting a document that discusses ways of handling plutonium. The document contains various warnings about safely dealing with such a dangerous substance. You want each warning to appear in boldface text so that it will stand out. However, you don't know which elements these warnings will be. Some warnings could be entire paragraphs, while others could be a single item within a lengthy list or a small section of text. So, you can't define a rule using simple selectors of any kind. Suppose you tried this route:
p {font-weight: bold;}
All paragraphs would be bold, not just those that contain warnings. You need a way to select only the text that contains warnings, or more precisely, a way to select only those elements that are warnings. How do you do it? You apply styles to parts of the document that have been marked in a certain way, independent of the elements involved, by using class selectors.
The most common way to apply styles without worrying about the elements involved is to use class selectors. Before you can use them, however, you need to modify your actual document markup so that the class selectors will work. Enter the class attribute:
<p class="warning">When handling plutonium, care must be taken to avoid 
the formation of a critical mass.</p>
<p>With plutonium, <span class="warning">the possibility of implosion is
very real, and must be avoided at all costs</span>. This can be accomplished 
by keeping the various masses separate.</p>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Attribute Selectors
When it comes to both class and ID selectors, what you're really doing is selecting values of attributes. The syntax used in the previous two sections is particular to HTML, SVG, and MathML documents (as of this writing). In other markup languages, these class and ID selectors may not be available. To address this situation, CSS2 introduced attribute selectors, which can be used to select elements based on their attributes and the values of those attributes. There are four types of attribute selectors.
Attribute selectors are supported by the Opera and Gecko browsers but not by Internet Explorer through IE5/Mac and IE6/Win.
If you want to select elements that have a certain attribute, regardless of the attribute's value, you can use a simple attribute selector. For example, to select all h1 elements that have a class attribute with any value and make their text silver, write:
h1[class] {color: silver;}
So given the following markup:
<h1 class="hoopla">Hello</h1>
<h1 class="severe">Serenity</h1>
<h1 class="fancy">Fooling</h1>
you get the result shown in Figure 2-10.
Figure 2-10: Selecting elements based on their attributes
This strategy is very useful in XML documents, as XML languages tend to have element and attribute names that are very specific to their purpose. Consider an XML language that is used to describe planets of the solar system (we'll call it PlanetML). If you want to select all planet elements with a moons attribute and make them boldface, thus calling attention to any planet that has moons, you would write:
planet[moons] {font-weight: bold;}
This would cause the text of the second and third elements in the following markup fragment to be boldfaced, but not the first:
<planet>Venus</planet>
<planet moons="1">Earth</planet>
<planet moons="2">Mars</planet>
In HTML documents, you can use this feature in a number of creative ways. For example, you could style all images that have an
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Document Structure
As I've mentioned before, CSS is powerful because it uses the structure of HTML documents to determine appropriate styles and how to apply them. That's only part of the story since it implies that such determinations are the only way CSS uses document structure. Structure plays a much larger role in the way styles are applied to a document. Let's take a moment to discuss structure before moving on to more powerful forms of selection.
In order to understand the relationship between selectors and documents, you need to once again examine how documents are structured. Consider this very simple HTML document:
<html>
<head>
 <base href="http://www.meerkat.web/">
 <title>Meerkat Central</title>
</head>
<body>
 <h1>Meerkat <em>Central</em></h1>
 <p>
 Welcome to Meerkat <em>Central</em>, the <strong>best meerkat web site 
 on <a href="inet.html">the <em>entire</em> Internet</a></strong>!</p>
 <ul>
  <li>We offer:
   <ul>
    <li><strong>Detailed information</strong> on how to adopt a meerkat</li>
    <li>Tips for living with a meerkat</li>
    <li><em>Fun</em> things to do with a meerkat, including:
     <ol>
      <li>Playing fetch</li>
      <li>Digging for food</li>
      <li>Hide and seek</li>
     </ol>
    </li>
   </ul>
  </li>
  <li>...and so much more!</li>
 </ul>
 <p>
 Questions? <a href="mailto:suricate@meerkat.web">Contact us!</a>
 </p>
</body>
</html>
Much of the power of CSS is based on the parent-child relationship of elements. HTML documents (actually, most structured documents of any kind) are based on a hierarchy of elements, which is visible in the "tree" view of the document (Figure 2-13). In this hierarchy, each element fits somewhere into the overall structure of the document. Every element in the document is either the parent or the child of another element, and it's often both.
Figure 2-13: A document tree structure
An element is said to be the parent of another element if it appears directly above that element in the document hierarchy. For example, in Figure 2-13, the first
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Pseudo-Classes and Pseudo-Elements
Things get really interesting with pseudo-class selectors and pseudo-element selectors. These selectors let you assign styles to structures that don't necessarily exist in the document, or to phantom classes that are inferred by the state of certain elements, or even by the state of the document itself. In other words, the styles are applied to pieces of a document based on something other than the structure of the document, and in a way that cannot be precisely deduced simply by studying the document's markup.
It may sound like I'm applying styles at random, but I'm not. Instead, I'm applying styles based on somewhat ephemeral conditions that can't be predicted in advance. However, the circumstances under which the styles will appear are, in fact, well-defined. Think of it this way: during a sporting event, whenever the home team scores, the crowd will cheer. You don't know exactly when during a game the scoring will happen, but when it does, the crowd will cheer, just as predicted. The fact that you can't predict the moment of the cause doesn't make the effect any less expected.
Let's begin by examining pseudo-class selectors since they're better supported by browsers and are therefore more widely used.
Consider the anchor element (a), which, in HTML and XHTML, establishes a link from one document to another. Anchors are always anchors, of course, but some anchors refer to pages that have already been visited, while others refer to pages that have yet to be visited. You can't tell the difference by simply looking at the HTML markup, because in the markup, all anchors look the same. The only way to tell which links have been visited is by comparing the links in a document to the user's browser history. So, there are actually two basic types of anchors: visited and unvisited. These types are known as pseudo-classes , and the selectors that use them are called pseudo-class selectors.
To better understand these classes and selectors, consider how browsers behave with regard to links. The Mosaic convention designated that links to pages you hadn't visited were blue, and links to already visited pages were red (the red became purple in succeeding browsers such as Internet Explorer). So, if you could insert classes into anchors, such that any anchor already visited would have a class of, say, "visited," then you could write a style to make such anchors red:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Summary
By using selectors based on the document's language, authors can create CSS rules that apply to a large number of similar elements just as easily as they can construct rules that apply in very narrow circumstances. The ability to group together both selectors and rules keeps style sheets compact and flexible, which incidentally leads to smaller file sizes and faster download times.
Selectors are the one thing that user agents usually have to get right because the inability to correctly interpret selectors pretty much prevents a user agent from using CSS at all. On the flip side, it's crucial for authors to correctly write selectors because errors can prevent the user agent from applying the styles as intended. An integral part of correctly understanding selectors and how they can be combined is an understanding of how selectors relate to document structure and how mechanisms—such as inheritance and the cascade itself—come into play when determining how an element is to be styled. This is the subject of the next chapter.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Structure and the Cascade
Chapter 2 showed how document structure and CSS selectors allow you to apply a wide variety of styles to elements. Knowing that every valid document generates a structural tree, you can create selectors that target elements based on their ancestors, attributes, sibling elements, and more. The structural tree is what allows selectors to function and is also central to a similarly crucial aspect of CSS: inheritance.
Inheritance is the mechanism by which some property values are passed on from an element to its descendants. In determining which values should apply to an element, a user agent must consider not only inheritance but also the specificity of the declarations, as well as the origin of the declarations themselves. This process of consideration is what's known as the cascade. We will explore the interrelation between these three mechanisms—specificity, inheritance, and the cascade—in this chapter.
Above all, regardless of how abstract things may seem, keep going! Your perseverance will be rewarded.
You know from Chapter 2 that you can select elements using a wide variety of means. In fact, it's possible that the same element could be selected by two or more rules, each with its own selector. Let's consider the following three pairs of rules. Assume that each pair will match the same element:
h1 {color: red;}
body h1 {color: green;}

h2.grape {color: purple;}
h2 {color: silver;}

html > body table tr[id="totals"] td ul > li {color: maroon;}
li#answer {color: navy;}
Obviously, only one of the two rules in each pair can win out, since the matched elements can be only one color or the other. How do you know which one will win?
The answer is found in the specificity of each selector. For every rule, the user agent evaluates the specificity of the selector and attaches it to each declaration in the rule. When an element has two or more conflicting property declarations, the one with the highest specificity will win out.
This isn't the whole story in terms of conflict resolution. In fact, all style conflict resolution is handled by the cascade, which has its own section later in this chapter.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Specificity
You know from Chapter 2 that you can select elements using a wide variety of means. In fact, it's possible that the same element could be selected by two or more rules, each with its own selector. Let's consider the following three pairs of rules. Assume that each pair will match the same element:
h1 {color: red;}
body h1 {color: green;}

h2.grape {color: purple;}
h2 {color: silver;}

html > body table tr[id="totals"] td ul > li {color: maroon;}
li#answer {color: navy;}
Obviously, only one of the two rules in each pair can win out, since the matched elements can be only one color or the other. How do you know which one will win?
The answer is found in the specificity of each selector. For every rule, the user agent evaluates the specificity of the selector and attaches it to each declaration in the rule. When an element has two or more conflicting property declarations, the one with the highest specificity will win out.
This isn't the whole story in terms of conflict resolution. In fact, all style conflict resolution is handled by the cascade, which has its own section later in this chapter.
A selector's specificity is determined by the components of the selector itself. A specificity value is expressed in four parts, like this: 0,0,0,0. The actual specificity of a selector is determined as follows:
  • For every ID attribute value given in the selector, add 0,1,0,0.
  • For every class attribute value, attribute selection, or pseudo-class given in the selection, add 0,0,1,0.
  • For every element and pseudo-element given in the selector, add 0,0,0,1. CSS2 contradicted itself as to whether pseudo-elements had any specificity at all, but CSS2.1 makes it clear that they do, and this is where they belong.
  • Combinators and the universal selector do not contribute anything to the specificity (more on these values later).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Inheritance
As important as specificity may be to understanding how declarations are applied to a document, another key concept is that of inheritance. Inheritance is the mechanism by which styles are applied not only to a specified element, but also to its descendants. If a color is applied to an h1 element, for example, then that color is applied to all text in the h1, even the text enclosed within child elements of that h1:
h1 {color: gray;}

<h1>Meerkat <em>Central</em></h1>
Both the ordinary h1 text and the em text are colored gray because the em element inherits the value of color. If property values could not be inherited by descendant elements, the em text would be black, not gray, and you'd have to color that element separately.
Inheritance also works well with unordered lists. Let's say you apply a style of color: gray; for ul elements:
ul {color: gray;}
You expect that a style that is applied to a ul will also be applied to its list items, and to any content of those list items. Thanks to inheritance, that's exactly what happens, as Figure 3-3 demonstrates.
Figure 3-3: Inheritance of styles
It's easier to see how inheritance works by turning to a tree diagram of a document. Figure 3-4 shows the tree diagram for a very simple document containing two lists: one unordered and the other ordered.
Figure 3-4: A simple tree diagram
When the declaration color: gray; is applied to the ul element, that element takes on that declaration. The value is then propagated down the tree to the descendant elements and continues on until there are no more descendants to inherit the value. Values are never propagated upward; that is, an element never passes values up to its ancestors.
There is an exception to the upward propagation rule in HTML: background styles applied to the body element can be passed to the html element, which is the document's root element and therefore defines its canvas.
Inheritance is one of those things about CSS that is so basic that you almost never think about it unless you have to. However, you should still keep a few things in mind.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Cascade
Throughout this chapter, we've skirted one rather important issue: what happens when two rules of equal specificity apply to the same element? How does the browser resolve the conflict? For example, say you have the following rules:
h1 {color: red;}
h1 {color: blue;}
Which one wins? Both have a specificity of 0,0,0,1, so they have equal weight and should both apply. That simply can't be the case because the element can't be both red and blue. But which will it be?
Finally the name "Cascading Style Sheets" makes some sense. CSS is based on a method of causing styles to cascade together made possible by combining inheritance and specificity. The cascade rules for CSS2.1 are simple enough:
  1. Find all declarations that contain a selector that matches a given element.
  2. Sort by explicit weight all declarations applying to the element. Those rules marked !important are given higher weight than those that are not. Also sort by origin all declarations applying to a given element. There are three origins: author, reader, and user agent. Under normal circumstances, the author's styles win out over the reader's styles. !important reader styles are stronger than any other styles, including !important author styles. Both author and reader styles override the user agent's default styles.
  3. Sort by specificity all declarations applying to a given element. Those elements with a higher specificity have more weight than those with lower specificity.
  4. Sort by order all declarations applying to a given element. The later a declaration appears in the style sheet or document, the more weight it is given. Declarations that appear in an imported style sheet are considered to come before all declarations within the style sheet that imports them.
In order to be perfectly clear about how this all works, let's consider three examples that illustrate the last three of the four cascade rules.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Summary