The title basically says it all.
Suppose I have an element which I want to change color on :hover
, but while clicked, I want it to swit
This is the expected behavior in so far as most people always place the :hover
pseudo-class at the end of the group of rules.
Order of declaration matters with pseudo-classes (see more here: http://reference.sitepoint.com/css/pseudoclasses), so the final rules get precedence, as with other rules in CSS.
For most people, I think the desired behavior:
a:link {
⋮ declarations
}
a:visited {
⋮ declarations
}
a:hover {
⋮ declarations
}
Since the :active
is not so useful it is left out... or combined with a:link
and a:visited
... and then it is overridden by a:hover
W3C spells it out here:
Note that the A:hover must be placed after the A:link and A:visited rules, since otherwise the cascading rules will hide the 'color' property of the A:hover rule. Similarly, because A:active is placed after A:hover, the active color (lime) will apply when the user both activates and hovers over the A element.
http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
Even W3schools gets this one right:
Note: a:hover MUST come after a:link and a:visited in the CSS definition in order to be effective!!
Note: a:active MUST come after a:hover in the CSS definition in order to be effective!!
http://www.w3schools.com/css/css_pseudo_classes.asp
This is how it works, and I'll try to explain why. As we know CSS will continue searching the document when applying styles and apply the style that is most specific to the element.
Example:
li.betterList { better list styling here }
Is more specific and will overwrite
li { list styling here }
And these Puesdo selectors are all considered the same specificity and thus the last line will overwrite the previous one. This is confirmed by the note on W3Schools
Note: :active MUST come after :hover (if present) in the CSS definition in order to be effective!
you can also throw this CSS on your jsfidle and watch it overwrite since they are the same specificity
.works {background: red}
.works {background: green}
Because in the first code you defined :hover
after you defined :active
, so :hover
"overwrote" :active
. In the second, it's the other way around, :active
overwrites :hover
.
yes this is expected behavior,
lets take a look at another example. just adding two classes,
<ul>
<li class="item first">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item last">item</li>
</ul>
here the class first also comes together with the class item. but if we declare our css in the wrong order that would not give the wanted behavior
.first { background: blue; }
.item { background: red; }
as you can see, the last matching selector will be used. it is the same as your example, no mather what is more logic, the 2 pseudo-classes are concidered equal, thus the same rules apply the last matching defenition wins.
edit
pseudoclasses are equals, it is the one defined last that wins! here is a jsFiddle that proves my point :link defined after :hover, :link wins (test) so, your statement of :hover overriding :link is wrong, its just the same like with :active, its all about the order.
The active state must be declared after the hover state, in your CSS you're clumping together the active state before the active state so it's not being triggered.
If you state the proper order of operation it works, like below, it works fine.
a.noworks:link, a.noworks:visited {
background: red;
}
a.noworks:hover {
background: green;
}
a.noworks:active {
background: red;
}
So, to answer your question, yes this is the expected behavior.
Here is the order of operation:
a:link
a:visited
a:hover
a:active
EDIT:
Sorry, I misunderstand the question.
Basically when you are in active state (with a mouse pointer) you are actually in hover state too. So based on CSS rules it would read the last one in stylesheet.
When you hover over a link and hold down the mouse key It's like this if we take pseud classes as normal classes :
<a class="active hover"></a>
So if your css was
.active{color:green}
.hover{color:red}
it would apply red
but if your css was
.hover{color:red}
.active{color:green}
It would apply green
From W3C
a:link { color: red } /* unvisited links */ a:visited { color: blue } /* visited links */ a:hover { color: yellow } /* user hovers */ a:active { color: lime } /* active links */
Note that the A:hover must be placed after the A:link and A:visited rules, since otherwise the cascading rules will hide the 'color' property of the A:hover rule. Similarly, because A:active is placed after A:hover, the active color (lime) will apply when the user both activates and hovers over the A element.