Take the 2-minute tour ×

Consider the following example: http://jsfiddle.net/j6SpZ/


<div class="container">
    <a class="pink">Pink</a>
    <a class="gray">Gray</a>


a {
    border: 1px solid black;
    padding: 20px;
    display: block;
a.gray { background-color: gray; }
a:hover { background-color: teal; }
.container a { background-color: transparent; }
a.pink { background-color: pink; }


So, everything happens according to the spec.

The style precedence values on the last four selectors are all (0,0,1,1): 1 class + 1 element. You get the expected transparent background for the first and third boxes (even on hover) because .container a comes after a.gray and a:hover. You get pink on the second one because a.pink comes after .container a. Cool (if I've misinterpreted the spec, let me know, but I think I'm on the money).

But my question revolves around the semanticity of allowing selectors on parent elements have the same impact on specificity as selectors on the modified element. I feel that the gray class selector is definitely "closer" and more specific to the element than the container class selector on the parent, and that the a.gray style declaration "should" have more precedence.

Is there a way to actually make this so, or a philosophy I can follow to resolve the dissonance in my thinking?

The actual application:

I have option button styling that amounts to the following:

.options a { background-color: gray; }
.options a:hover { background-color: blue; }

Basically, the option buttons are gray and blue on hover. Now, I want to put these in a special area where I want the default behavior to have a transparent background:

.env1 .subenv1 .options a { background-color: transparent; }

But now, this declaration takes precedence even over the :hover, and I don't want it to. I still want its hover behavior to be the same; I just want the default background to be transparent. Of course, I can re-declare the hover styles, but this repeats that information, which is unideal. I have no problem sucking it up and just re-declaring it, which is what I'm doing now, but surely, there must be a way to get this to make sense in my head.

share|improve this question
A simplified jsFiddle demo of the application would be nice to play around with. –  BoltClock Jun 12 '11 at 4:18
By the way, the spec doesn't take into account what elements a class or pseudo-class selector is "attached" to. It just asks browsers to count the number of each simple selector appearing in the sequence and add them up like you said, and I don't know of a way to work around that behavior without changing selectors or redeclaring rules. –  BoltClock Jun 12 '11 at 4:26
@BoltClock: Here you go: jsfiddle.net/FSRfN. Your observation how the spec works is astute and correct. With this question, I assume that the reason the spec doesn't work out exactly like it does in my head is that there's some other, better pattern to accomplish what I'm going for. So basically, I'm on the hunt for the better pattern that will allow me to set non-hover styles for an element with parent selectors that don't also override hover styles. –  Steven Xu Jun 12 '11 at 5:52

4 Answers 4

What if you move the :hover declaration to the end? Seems to work in your fiddle.

I don't know if it constitutes a philosophy, but CSS does consider order of declaration when calculating the precedence of rules. It's not always possible to achieve what you want this way, but maybe in the case you're talking about.

share|improve this answer
But in the real application, this won't work because the more specific selector still takes precedence. The last 4 selectors in the fiddle are all equally specific. –  BoltClock Jun 12 '11 at 4:42
:hover will work the sanitized initial example, but it unfortunately stops working when the precedence of preceding selectors comes to be greater, which is the case in my "actual application" section. Sorry for arranging my question that way; that was an error on my part. –  Steven Xu Jun 12 '11 at 5:58

If you always want the hover style to be in effect you can add !important to the style. This will mean that the background-color on the :hover will take precedence over other declarations. I have demonstrated this in your fiddle here.

It's best practices to avoid using important, however if it is considered to the be the final hover style for that element it's okay to use.

share|improve this answer
Good point using !important. I've been able to resist so far mostly due to it being instilled in my mind that thou shalt not use it. Now that I think of it, it might actually seem pertinent in this case. If I want the hover styles to go through despite parent selectors that badly, perhaps they're "important" enough to be !important... –  Steven Xu Jun 12 '11 at 5:57

A selector like ".container a.gray" has higher specificity and should fix the problem. Or move the a.gray rule to the end, later rules have higher specificity.

share|improve this answer

@Sam152, @harpo, and @chrisdowney are all sort of correct. In essence, you need to change the CSS weight (or specificity) of each rule to fit an exact order you desire. Getting that balance in this case can be tricky. You can use a mix of adding selectors (@chrisdowney's answer), rule order (@harpo's answer), or adding !important (@Sam152's answer). They all alter the order the rules will be applied.

Specifics on CSS specificity is a good tutorial on how to calculate the value and therefore be able to adjust any of the rules to fit your specific rule order requirements.

Make sure to use a CSS browser developer tool like Firebug (Firefox), Developer Tools (Chrome), "F12 Develeper Tools" (IE), or similar to help you determine the order that is applied, and to quickly see the affects of your adjustments.

!important is generally discouraged because it limits you later... But you may have reached a point where being perfectly designed for robustness may be getting in the way of practically getting the job done and shipped. And depending on how complex the rest of the site/rule set is, it may not even make much of a difference anyway.

In the end, all of the mentioned adjustments would work fine in your case. That means there are several solutions to your problem. Use whichever is most comfortable to you.

share|improve this answer

Your Answer


