CSS precedence

Most of the answers are correct in saying that this is a specificity problem but are incorrect or incomplete in explaining the specificity rules.

Basically in your case .rightColoumn * is “more specific” than td and so that rule wins even though it comes earlier.

The CSS 2.1 rules are located here. These rules are:

  • count 1 if the declaration is from is a ‘style’ attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element’s “style” attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
  • count the number of ID attributes in the selector (= b)
  • count the number of other attributes and pseudo-classes in the selector (= c)
  • count the number of element names and pseudo-elements in the selector (= d)

Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.

So in your case you have two rules:

.rightColumn * {} /* a = 0, b = 0; c = 1, d = 0 : Specificity = 0010*/
td {} /* a = 0, b = 0, c = 0, d = 1 : Specificity = 0001 */

0001 is lower than 0010 and thus the first rule wins.

There are two ways to fix this:

  1. Use !important to make a rule more “important”. I’d avoid doing this because it is confusing when you have lots of rules spread out over several files.
  2. Use a higher-specifity selector for the td you want to modify. You can add a class name to it or an id and this will allow you to supersede the rule from the linked CSS file.

Example:

<style>
  .rightColomn * { padding: 0; } /* 0010 */
  td#myUnpaddedTable { padding: 10px; } /* 0101 */
  td.anUnpaddedTable { padding: 10px; } /* 0011 */ 
</style>

Edit: Fixed the specificity rules for *. David’s comment prompted me to re-read the spec, which does show that the * selector contributes nothing to the specificity score.

Leave a Comment