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.


As others have mentioned, you have a specificity problem. When determining which of two rules should take precedence, the CSS engine counts the number of #ids in each selector. If one has more than the other, it's used. Otherwise, it continues comparing .classes and tags in the same way. Here, you have a class on the stylesheet rule, but not on the inline rule, so the stylesheet takes precedence.

You can override this with !important, but that's an awfully big hammer to be using here. You're better off improving the specificity of your inline rule. Based on your description, it sounds like your .rightColumn element either is or contains a table and you'd like the cells in that table to have extra spacing? If so, the selector you're looking for is ".rightColumn td", which is more specific than the stylesheet rule and will take precedence.


The easiest way to get it to work is to add "!important" to CSS to guarantee its precedence (unless you've got multiple !important rules):

td {
    padding-left: 10px !important;
} 

If you're looking for an answer without !important, you should read into CSS specificity specifications. The linked site has a good explanation of how it works, though basically it goes from most important to least, with id selectors most important, class selectors second, and element selectors third.


Try this instead:

td.rightColumn * {margin: 0; padding: 0;}

The td in the external stylesheet is more specific so it wins out. If you qualify the rightColumn class with an element name then the page-level styles will be applied.


You could try adding the ! important flag to your inline css.

e.g.

td { padding-left:10px ! important; }

Also, for general rules on css rule ordering, have a look at this :

http://www.w3.org/TR/CSS2/cascade.html#specificity