My webpage contains:
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<style type="text/css">
td {
padding-left:10px;
}
</style>
The referenced stylesheet contains:
.rightColumn * {margin: 0; padding: 0;}
I have a table in the rightcolumn
ID where I want the cells to have a little padding. However, the referenced stylesheet is taking precedence over the inline styling. I see this visually and also via Firebug. If I turn off the padding:0
instruction in Firebug, the padding-left takes effect.
How can I get the padding-left
to work?
-
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.
Rahul : Watch out when using !important. It will increase maintenance problems if you have other people working with the code that aren't familiar with your usage of the !important rule.Andrew Hare : Not to mention it breaks precedence which is confusing if you are looking at a rule that ought to be applied but isn't.Daniel Lew : I agree that !important should be used sparingly, but I find it similarly problematic when someone starts over-complicating their selectors just so they are more specific. For this example, it'd be td.rightColumn * { ... }, which is a horrific change to an otherwise simple selector. -
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 therightColumn
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
: Wow, this was my first question posted to StackOverflow. I thank you all for your responses. They made me think more deeply about the issue. -
Do this:
.rightColumn *, td.rightColumn * { margin: 0; padding: 0; }
Precedence in CSS is as follows:
- If some rule has an ID, then it will precede anything else.
- If some rule has a class attribute, it will precede tag-only rules.
- If two rules have both IDs or tags, then the number of them untie the "fight".
Example:
<style type="text/css"> #myid{ padding: 10px; } .class{ padding: 20px; } </style> <div id="myid" class="class"></div>
Although your div has both ID and a class, the ID rule will override the .class rule.
To read more about CSS rules priorities, I'd recommend http://www.w3.org/TR/CSS2/cascade.html#specificity.
-
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
#id
s in each selector. If one has more than the other, it's used. Otherwise, it continues comparing.class
es andtag
s 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 atable
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. -
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" thantd
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:
- 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. - 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.
David Kolar : I concur. Based on the W3C page, though, I don't think that the star selector counts towards d-level (or any-level) specificity, so .rightColumn * should score 0010. I'd also recommend .rightColumn td {} as way to set the padding; it yields a good-enough score of 0011.Mr. Shiny and New : @David Kolar: Thanks, fixed.
0 comments:
Post a Comment