Chapter 5. Managing Multiple Styles: The Cascade

As you create increasingly complex style sheets, you'll sometimes wonder why a particular element on a page looks the way it does. CSS's inheritance feature, as discussed in the previous chapter, creates the possibility that any tag on a page is potentially affected by any of the tags that wrap around it. For example, the <body> tag can pass properties on to a paragraph, and a paragraph may pass its own formatting instructions on to a link within the paragraph. In other words, that link can inherit CSS properties from both the <body> and the <p> tag—essentially creating a kind of Frankenstyle that combines parts of two different CSS styles.

Then there are times when styles collide—the same CSS property is defined in multiple styles, all applying to a particular element on the page (for example, a <p> tag style in an external style sheet and another <p> tag style in an internal style sheet). When that happens, you can see some pretty weird stuff, like text that appears bright blue, even though you specifically applied a class style with the text color set to red. Fortunately, there's actually a system at work: a basic CSS mechanism known as the cascade, which governs how styles interact and which styles get precedence when there's a conflict.

Note

This chapter deals with issues that arise when you build complex style sheets that rely on inheritance and more sophisticated types of selectors like descendent selectors (ID Selectors: Specific Page Elements). The rules are all pretty logical, but they're about as fun to master as the tax code. If that's got your spirits sagging, consider skipping the details and doing the tutorial on Tutorial: The Cascade in Action to get a taste of what the cascade is and why it matters. Or jump right to the next chapter which explores fun and visually exciting ways to format text. You can always return to this chapter later, after you've mastered the basics of CSS.

The cascade is a set of rules for determining which style properties get applied to an element. It specifies how a web browser should handle multiple styles that apply to the same tag and what to do when CSS properties conflict. Style conflicts happen in two cases: through inheritance when the same property is inherited from multiple ancestors, and when one or more styles apply to the same element (maybe a <p> tag style in an external style sheet and another <p> tag style in an internal style sheet).

As you'll read in the last chapter, CSS inheritance ensures that related elements—like all the words inside a paragraph, even those inside a link or another tag—share similar formatting. It spares you from creating specific styles for each tag on a page. But since one tag can inherit properties from any ancestor tag—a link, for example, inheriting the same font as its parent <p> tag—determining why a particular tag is formatted one way can be a bit tricky. Imagine a font family applied to the <body> tag, a font size applied to a <p> tag, and a font color applied to an <a> tag. Any <a> tag inside of a paragraph would inherit the font from the body and the size from the paragraph. In other words, the inherited styles combine to form a hybrid style.

The page shown in Figure 5-1 has three styles: one for the <body>, one for the <p> tag, and one for the <strong> tag. The CSS looks like this:

body { font-family: Verdana, Arial, Helvetica, sans-serif; }
p { color: #F30; }
strong { font-size: 24px; }

The <strong> tag is nested inside a paragraph, which is inside the <body> tag. That <strong> tag inherits from both of its ancestors, so it inherits the font-family property from the body and the color property from its parent paragraph. In addition, the <strong> tag has a bit of CSS applied directly to it—a 24px font size. The final appearance of the tag is a combination of all three styles. In other words, the <strong> tag appears exactly as if you'd created a style like this:

strong {
  font-family: Verdana, Arial, Helvetica, sans-serif;
  color: #F30;
  font-size: 24px;
}

Taking the "nearest ancestor" rule to its logical conclusion, there's one style that always becomes king of the CSS family tree—any style applied directly to a given tag. Suppose a font color is set for the body, paragraph, and strong tags. The paragraph style is more specific than the body style, but the style applied to the <strong> tag is more specific than either one. It formats the <strong> tags and only the <strong> tags, overriding any conflicting properties inherited from the other tags (see Figure 5-2, number 2). In other words, properties from a style specifically applied to a tag beat out any inherited properties.

This rule explains why some inherited properties don't appear to inherit. A link inside a paragraph whose text is red still appears browser-link blue. That's because browsers have their own predefined style for the <a> tag, so an inherited text color won't apply.

Inheritance is one way that a tag can be affected by multiple styles. But it's also possible to have multiple styles apply directly to a given tag. For example, say you have an external style sheet with a <p> tag style and attach it to a page that has an internal style sheet that also includes a <p> tag style. And just to make things really interesting, one of the <p> tags on the page has a class style applied to it. So for that one tag, three different styles directly format it. Which style—or styles—should the browser obey?

The answer: It depends. Based on the types of styles and the order in which they're created, a browser may apply one or more of them at once. Here are a few situations in which multiple styles can apply to the same tag:

If more than one style applies to a particular element, then a web browser combines the properties of all those styles, as long as they don't conflict. An example will make this concept clearer. Imagine you have a paragraph that lists the name of the web page's author, including a link to his email address. The HTML might look like this:

<p class="byline">Written by <a href="mailto:jean@cosmofarmer.com">JeanGraine
de Pomme</a></p>

Meanwhile, the page's style sheet has three styles that format the link:

a { color: #6378df; }
p a { font-weight: bold; }
.byline a { text-decoration: none; }

The first style turns all <a> tags powder blue; the second style makes all <a> tags that appear inside a <p> tag bold; and the third style removes the underline from any links that appear inside an element with the byline class applied to it.

All three styles apply to that very popular <a> tag, but since none of the properties are the same, there are no conflicts between the rules. The situation is similar to the inheritance example (Inherited Styles Accumulate): the styles combine to make one überstyle containing all three properties, so this particular link appears powder blue, bold, and underline-free.