< Day Day Up > |
3.3 The CascadeThroughout 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:
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. 3.3.1 Sorting by Weight and OriginUnder the second rule, if two rules apply to an element, and one is marked !important, the important rule wins out: p {color: gray !important;} <p style="color: black;">Well, <em>hello</em> there!</p> Despite the fact that there is a color assigned in the style attribute of the paragraph, the !important rule wins out, and the paragraph is gray. This gray is inherited by the em element as well. Furthermore, the origin of a rule is considered. If an element is matched by normal-weight styles in both the author's style sheet and the reader's style sheet, then the author's styles are used. For example, assume that the following styles come from the indicated origins: p em {color: black;} /* author's stylesheet */ p em {color: yellow;} /* reader's stylesheet */ In this case, emphasized text within paragraphs is colored black, not yellow, because normal-weight author styles win out over normal-weight reader styles. However, if both rules are marked !important, the situation changes: p em {color: black !important;} /* author's stylesheet */ p em {color: yellow !important;} /* reader's stylesheet */ Now the emphasized text in paragraphs will be yellow, not black. As it happens, the user agent's default styles—which are often influenced by the user preferences—are figured into this step. The default style declarations are the least influential of all. Therefore, if an author-defined rule applies to anchors (e.g., declaring them to be white), then this rule overrides the user agent's defaults. To sum up, in terms of declaration weight, there are five levels to consider. In order of most to least weight, these are:
Authors typically need to worry about only the first four weight levels, since anything declared will win out over the user agent styles. 3.3.2 Sorting by SpecificityAccording to the third rule, if conflicting declarations apply to an element and they all have the same weight, they should be sorted by specificity, with the most specific declaration winning out. For example: p#bright {color: silver;} p {color: black;} <p id="bright">Well, hello there!</p> Given the rules shown, the text of the paragraph will be silver, as illustrated in Figure 3-8. Why? Because the specificity of p#bright (0,1,0,0) overrode the specificity of p (0,0,0,1), even though the latter rule comes later in the style sheet. Figure 3-8. Higher specificity wins out over lower specificity3.3.3 Sorting by OrderFinally, under the fourth rule, if two rules have exactly the same weight, origin, and specificity, then the one that occurs later in the style sheet wins out. Therefore, let's return to our earlier example, where we find the following two rules in the document's style sheet: h1 {color: red;} h1 {color: blue;} Because its rule comes later in the style sheet, the value of color for all h1 elements in the document will be blue, not red. Any rule that is contained in the document, having a higher weight than the imported rule, wins out. This is true even if the rule is part of the document's style sheet and not part of an element's style attribute. Consider the following: p em {color: purple;} /* from imported stylesheet */ p em {color: gray;} /* rule contained within the document */ In this case, the second rule shown will win out over the imported rule because it is a part of the document's style sheet. For the purposes of this rule, styles specified in the style attribute of an element are considered to be at the end of the document's style sheet, which places them after all other rules. However, this is a largely academic point, since inline style declarations have a higher specificity than any style sheet selector in CSS2.1.
Order sorting is the reason behind the often recommended ordering of link styles. The recommendation is that you array your link styles in the order link-visited-hover-active, or LVHA, like this: :link {color: blue;} :visited {color: purple;} :hover {color: red;} :active {color: orange;} Thanks to the information in this chapter, you now know that the specificity of all these selectors is the same: 0,0,1,0. Because they all have the same weight, origin, and specificity, the last one that matches an element will win out. An unvisited link that is being "clicked" is matched by three of the rules—:link, :hover, and :active—and so the last one of those three declared will win out. Given the LVHA ordering, :active will win, which is likely what the author intended. Assume for a moment that you decided to ignore the common ordering and alphabetize your link styles instead. This would yield: :active {color: orange;} :hover {color: red;} :link {color: blue;} :visited {color: purple;} Given this ordering, no link would ever show :hover or :active styles because the :link and :visited rules come after the other two. Every link must be either visited or unvisited, so those styles will always override the :hover rule. Let's consider a variation on the LVHA order that an author might want to use. In this ordering, only unvisited links will get a hover style—visited links do not. Both visited and unvisited links will get an active style: :link {color: blue;} :hover {color: red;} :visited {color: purple;} :active {color: orange;} Of course, sometimes such conflicts arise when all the states attempt to set the same property. If each state styles a different property, then the order does not matter. In the following case, the link styles could be given in any order and still function: :link {font-weight: bold;} :visited {font-style: italic;} :hover {color: red;} :active {background: yellow;} You may also have realized that the order of the :link and :visited styles doesn't matter. You could order the styles LVHA or VLHA with no ill effect. However, LVHA tends to be preferred because it was recommended in the CSS2 specification and also because the mnemonic "LoVe—HA!" gained rather wide currency. (There's some bitterness out there, apparently.) The ability to chain pseudo-classes together eliminates these worries. The following could be listed in any order without any negative effects: :link {color: blue;} :visited {color: purple;} :link:hover {color: red;} :visited:hover {color: gray;} Because each rule applies to a unique set of link states, they do not conflict. Therefore, changing their order will not change the styling of the document. The last two rules do have the same specificity, but that doesn't matter. A hovered unvisited link will not be matched by the rule regarding hovered visited links, and vice versa. If we were to add active-state styles, then order would start to matter again. Consider: :link {color: blue;} :visited {color: purple;} :link:hover {color: red;} :visited:hover {color: gray;} :link:active {color: orange;} :visited:active {color: silver;} If the active styles were moved before the hover styles, they would be ignored. Again, this would happen due to specificity conflicts. The conflicts could be avoided by adding more pseudo-classes to the chains, like this: :link:hover:active {color: orange;} :visited:hover:active {color: silver;} Chained psuedo-classes, which lessen the worries about specificity and ordering, would be used much more if they were supported by Internet Explorer. 3.3.4 Non-CSS Presentational HintsIt is possible that a document will contain presentational hints that are not CSS—e.g., the font element. Non-CSS hints are treated as if they have a specificity of 0 and appear at the beginning of the author's style sheet. Such presentation hints will be overridden by any author or reader styles, but not by the user agent's styles. |
< Day Day Up > |