CSS Structure and Cascade

TOC

Structure

In the previous example page I used proper HTML structure in arranging major markup elements. That is, the page was framed with the HTML tag, and included a HEAD section and a BODY tag. Within the BODY, content blocks were organized with decreasingly important header (H1, H2, H3) tags, and under them, paragraphs. A search engine would love this page because it makes logical sense. There is no page that cannot be built using proper HTML structure.

Structure is important to the implementation of CSS due to a crucial feature: inheritance. Inheritance is the mechanism that causes property values of an element to affect its decendants (elements nested inside it in the page structure.)

Specificity

Remember that selectors can choose the elements that styles apply to. It is possible that the same element could be selected by two or more rules, each with its own selector. Look at these pairs of rules, and 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. Which will win?

The answer is in the specificity of the selectors. A selector's specificity is determined by the components of the selector, and is expressed as a value in four parts: 0,0,0,0. The actual specificity of a selector is determined by these rules:

Returning to our pairs of rules, let's fill in the specificities:

	h1 {color: red;}  /* 0,0,0,1 */
	body h1 {color: green;}  /* 0,0,0,2  (winner) */
	
	h2.grape {color: purple;} /* 0,0,1,1 (winner) */
	h2 {color: silver;} /* 0,0,0,1 */
	
	html > body table tr[id="totals"] td ul > li {color: maroon;} /* 0,0,1,7 */
	li#answer {color: navy} /* 0,1,0,1 (winner) */

It gets pretty complicated after that, because declarations have specificity too, but I just wanted you to be aware of what your browser goes through trying to apply your styles. The point is: if you don't get what you expect, start looking for conflicting or badly selected rules.

Inheritance

Much of the power of CSS is realized through exploitation of the parent-child relationship of elements in an HTML page. If a color is applied to an h1 element, the color is applied to all text within the element tags, even if there is another structural tag inside it. For example:

Web page:Markup:

Meerkat Central

h1 {color: green;}

<h1>Meerkat <em>Central</em></h1>

Both the regular text and the emphasized text are colored green because the <em> element inherits its parent's color property value.

Let's try another one. Inheritance also works well with unordered lists. Let's say you apply a style of color: green; for ul elements:

  • Oh don't you wonder why
  • Messy birds were made to fly
  • While man must trod the sand,
  • And look up wond'ring why?
  1. Better keep a hanky fancy
  2. Looking skyward may be chancy
  3. My dear father did remmand,
  4. Get an eyeful and you can't see!

The green style applied, as we expected, to the <li> elements that are children of the parent <ul>. But notice that the items in the ordered list below it are unaffected.

That is because the page structure breaks the inheritance; the selector only applies to the <ul> elements and its children -- its <li>'s, not the <ol> and its children:

	          body
	     +------------+
	     |            |
	    ul           ol
	 +---+---+    +---+---+
	 |   |   |    |   |   |
	li  li  li   li  li  li

To make the <li>'s under the <ol> also green, we'd have to do one of three things:

The first would require adding class="green" to the markup for both ul and ol tags, but it would allow us to use markup to choose which lists should be green. The second would color all list items in the page green, which might not be what we want. The third would accomplish the same as the second. Which one you choose depends a lot on how you structure the web site.

The Cascade

What happens when two rules of equal specificity apply to the same element? For example, if you have the two following rules in the stylesheet:

	h1 {color: red;}
	h1 {color: blue;}

Which one wins? Both have a specificity of 0,0,0,1 so they have equal weights and should both apply. That can't work, though because only one color can be applied at a time to a given element -- it's simply the physics of computer monitors.

The cascade rules are simple:

  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.
  3. Sort declarations by specificity. 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 stylesheet or document, the more weight is given. Declarations that appear in an imported stylesheet are considered to come before all declarations within the stylesheet that imports them.

<< Style Selectors | Index | Fonts >>