Book HomeCascading Style Sheets: The Definitive GuideSearch this book Friday 20th of April 2018 04:43:20 PM

2.8. The Cascade

Through all this, we've skirted one rather important issue: what happens when there are two rules of equal specificity that apply to the same element? How does the browser resolve the conflict?

For example, let's say we have the following rules:

H1 {color: red;}
H1 {color: blue;}

So which one wins? Both have a specificity of 1, so they have equal weight and should both apply. That simply can't be the case, though, because the element can't be both red and blue. It has to be one or the other. But which?

This is where the name "Cascading Style Sheets" finally makes some sense. CSS is based on a method of causing styles to cascade together -- a method that is made possible by the rules of inheritance and specificity, as it happens. The cascade rules 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 given 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 author styles win out over important reader styles in CSS1, but in CSS2, !important reader styles are stronger than any other styles. Either author or reader styles will override user agent 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, and declarations within STYLE attributes come later than those in the document's embedded style sheet.

In order to be perfectly clear about how this all works, let's consider an example that illustrates each of the four cascade steps. The first one is simple enough: find all rules whose selectors match a given element.

Under the second step, if two rules apply to an element, and one is marked !important, then the important rule wins out. Thus:

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, as shown in Figure 2-28. This gray is inherited by the EM element as well.

Figure 2-28

Figure 2-28. Sorting styles by their importance

Furthermore, the origin of a rule is considered. If an element is matched by 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 style sheet */
P EM {color: yellow;}   /* reader's style sheet */

In this case, we have the result shown in Figure 2-29, where the emphasized text is black.

Figure 2-29

Figure 2-29. Sorting styles by origin

As it happens, the browser's default styles -- which are often influenced by its preferences -- are figured into this step. The browser's default styles 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. If readers wish to enforce certain rules at all costs, then they must define them in a local style sheet and declare them to be !important, so that they will win out under step 1 of the cascade rules. In this case, though, it will be a case of the reader's styles overriding both the author's and browser's styles due to their importance.

According to the third step, if multiple rules apply to an element, then they should be sorted by specificity, with the most specific rule winning out. For example:

P#bright {color: silver;}
P EM {color: gray;}
P {color: black;}
<P ID="bright">Well, <EM>hello</EM> there!</P>
Figure 2-30

Figure 2-30. Sorting styles by specificity

As we can see from Figure 2-30, the text of the paragraph is silver, except for the EM text, which is gray. Why? Because the specificity of P#bright (101) overrode the specificity of P (1), even though the latter rule comes later in the style sheet. However, the EM text does not inherit the value silver, because it has an explicit rule associated with it, and the rule's specificity (2) overrides the inherited value of silver.

This is not a trivial point. For example, assume that a style sheet has been written such that all text in a toolbar is to be white on black:

#toolbar {color: white; background: black;}

This will work so long as the element with an ID of toolbar contains only plain text. If, however, the text within this element is all hyperlinks (A elements), then the user agent's styles for hyperlinks will take over -- because despite the fact the they're imported, they are explicit style assignments, so they override any inherited values. Usually, this means that they'll be colored blue, since the browser's style sheet probably contains an entry like this:

A:link {color: blue;}

In order to overcome this problem, the author would need to declare:

#toolbar A:link {color: white; background: black;}

By targeting the rule directly to the A elements within the toolbar, the author will get the result shown in Figure 2-31.

Figure 2-31

Figure 2-31. Using contextual selectors to overcome specificity

Lastly, under the fourth step, if two rules have exactly the same

This may be an interesting effect, but it isn't permissible under the CSS specification, and no other browser will do the same thing, so it's best to avoid this altogether.

Even worse, if you try applying padding to inline elements in Navigator 4.x, you get a huge mess. The same sorts of things that happen when you apply margins to inline elements will happen if you apply padding, so it is wise to avoid setting margins, borders, or padding on inline elements.

weight, origin, and specificity, then the one that occurs later in the style sheet wins out. Thus, let us return to our earlier example, where we find the following two rules in the document's style sheet:

H1 {color: red;}
H1 {color: blue;}

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 style sheet */
P EM {color: gray;}    /* rule contained within the document */

In this case, the second rule shown, since it is a part of the document's style sheet, will win out over the imported rule.

For the purposes of this rule, styles that are given 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. In addition, a STYLE attribute has a weight equivalent to that of an ID selector. Thus, the following code would result in black text, as shown in Figure 2-32:

#hello {color: red;}
<P ID="hello" STYLE="color: black;">Hello there!</P>
Figure 2-32

Figure 2-32. Sorting styles by their position

Here, the weight of the inline style (100) is equal to the weight of the rule #hello (100), so the winner is the rule that occurs later in the document.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.

disastrous consequences in small browsing environments like handheld devices. Furthermore, it forces you to declare a specific height and width, which gives up a lot of flexibility. Wouldn't it be better to define certain limits for the size of the height and width?

9.1.3.2. Limiting width and height

Should it become necessary or desirable, you can place limits on an element's width and

Figure 7-16

Figure 7-16. Collapsed versus uncollapsed margins

Correctly implemented user agents will collapse the verticallyadjacent margins, as shown in the first list in Figure 7-16, where there are 15-pixel spaces between eachlist item. The second list shows what would happen if the user agentdidn't collapse margins, resulting in 25-pixel spaces betweenlist items.

Another word to use, if you don't like "collapse,"is

As you can see, this property accepts any length value or a percentage. That's all. So if you want all H1 elements to have 10 pixels of padding on all sides, it's this easy, as the result shown in Figure 7-56 makes clear:

H1 {padding: 10px; background-color: silver;}
Figure 7-56

Figure 7-56. Padding applied to an H1 element

On the other hand, we might want H1 elements to have uneven padding and H2 elements to have regular padding, as shown in Figure 7-57:element. If no such element is inserted, then the line will go forever, forcing the user to scroll horizontally to read whatever can't be initially displayed <BR>in the browser window.</P>

Figure 4-21

Figure 4-21. Suppressing text-wrapping with the white-space property

In fact, you can use white-space to replace the nowrap attribute on table cells, as demonstrated in Figure 4-22:

TD {white-space: nowrap;}
<TABLE><TR>
<TD>The contents of this cell are not wrapped.</TD>
writing: Opera 3.6 for Windows, Internet Explorer 4.5 and 5 for
Macintosh, and Internet Explorer 5  for  Windows.

6.2.5. Getting Attached

Okay, so we can place the origin image for the background anywhere in the background of an element, and we can control (to a degree) how it tiles. As you may have already realized,