Specificity: Which Style Wins

The previous example is pretty straightforward. But what if the three styles listed on Inherited Styles Accumulate each had a different font specified for the font-family property? Which of the three fonts would a web browser pay attention to?

As you know if you've been reading carefully so far, the cascade provides a set of rules that helps a web browser sort out any property conflicts; namely, properties from the most specific style win. But as with the styles listed on Inherited Styles Accumulate, sometimes it's not clear which style is most specific. Thankfully, CSS provides a formula for determining a style's specificity that's based on a value assigned to the style's selector—a tag selector, class selector, ID selector, and so on. Here's how the system works:

Note

The math involved in calculating specificity is actually a bit more complicated than described here. But this formula works in all but the weirdest cases. To read how web browsers actually calculate specificity visit www.w3.org/TR/CSS21/cascade.html#specificity.

The bigger the number, the greater the specificity. So say you create the following three styles:

Then, say your web page has this HTML: <img id="logo" class="highlight" src="logo.gif" />. If you define the same property—such as the border property—in all three styles, then the value from the ID style (#logo ) always wins out.

Note

A pseudo-element (like :first-line for example) is treated like a tag selector and is worth 1 point. A pseudo-class (:link, for example) is treated like a class and is worth 10 points. (See Styling Paragraph Parts for the deal on these pseudo-things.)

Since descendent selectors are composed of several selectors—#content p, or h2 strong, for example—the math gets a bit more complicated. The specificity of a descendent selector is the total value of all of the selectors listed (see Figure 5-3).

When more than one style applies to a tag, a web browser must determine which style should "win out" in case style properties conflicts. In CSS, a style's importance is known as specificity and is determined by the type of selectors used when creating the style. Each type of selector has a different value, and when multiple selector types appear in one style—for example the descendent selector #banner p—the values of all the selectors used are added up.

Figure 5-3. When more than one style applies to a tag, a web browser must determine which style should "win out" in case style properties conflicts. In CSS, a style's importance is known as specificity and is determined by the type of selectors used when creating the style. Each type of selector has a different value, and when multiple selector types appear in one style—for example the descendent selector #banner p—the values of all the selectors used are added up.

Note

Inherited properties don't have any specificity. So even if a tag inherits properties from a style with a large specificity—like #banner—those properties will always be overridden by a style that directly applies to the tag.

It's possible for two styles with conflicting properties to have the same specificity. ("Oh brother, when will it end?" Soon, comrade, soon. The tutorial is coming up.) A specificity tie can occur when you have the same selector defined in two locations. You may have a <p> tag selector defined in an internal style sheet and an external style sheet. Or two different styles may simply have equal specificity values. In case of a tie, the style appearing last in the style sheet wins.

Here's a tricky example using the following HTML:

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

In the style sheet for the page containing the above paragraph and link, you have two styles:

p .email { color: blue; }
.byline a { color: red; }

Both styles have a specificity of 11 (10 for a class name and 1 for a tag selector) and both apply to the <a> tag. The two styles are tied. Which color does the browser use to color the link in the above paragraph? Answer: Red, since it's the second (and last) style in the sheet.

Now suppose the style sheet looked like this instead:

.byline a { color: red; }
p .email { color: blue; }

In this case, the link would be red. Since .byline a appears after p .email in the style sheet, its properties win out.

What happens if you've got conflicting rules in an external and an internal style sheet? In that case, the placement of your style sheets (within your HTML file) becomes very important. If you first add an internal style sheet using the <style> tag (Understanding Style Sheets) and then attach an external style sheet farther down in the HTML using the <link> tag (External Style Sheets), then the style from the external style sheet wins. (In effect, it's the same principle at work that you just finished reading about: The style appearing last wins. ) The bottom line: Be consistent in how you place external style sheets. It's best to list any external style sheets first, and then include any internal styles.