What is the difference between .hover and :hover? - css

I was digging some css codes written by someone and I found this:
li.hover, li:hover {
}
Is there any difference between .hover and :hover?
Maybe some browsers act differently for hover?!

:hover is a psuedo-class while .hover is a selector for the class hover. These symbols (: and .) don't change meaning from any other CSS selector construct: see the W3C CSS Level 3 Recommendation for all the details.
Presumably there is some JavaScript to toggle the hover class, perhaps because of lack of :hover support for LI elements in a "legacy" browser. I know that IE5/6 (ick!) only supported :hover for links, however:
"Modern" GUI browsers correctly support :hover.
(And, as always, make sure the page is not in "quirksmode" :-)
Happy coding.

.hover is just a class name (possibly used to mean "something I [the coder] want to look the same as a hovered item", whereas :hover is the psuedo-class for when the mouse is over it. (Personally I use .hl instead of .hover for something like that)

.hover is a normal class name like any other class name, it has no special meaning.
:hover is the hover pseudo-class which you cannot create yourself, which is only applied when the user hovers over an element with the mouse.

Yes: one's a class (that's .hover) and the other's a pseudo-class (:hover). The pseudo-class will be matched when the mouse is over the element, and the class will be matched when the element has that class.
Presumably, the class is added by JavaScript. This could be for compatibility (some version of IE, I believe IE6 or IE7, only supports :hover on <a> elements) or it could be for extra features (sticky highlighting, for example).

Related

Why not :visited instead of a:visited for links?

Every example and stylesheet I've looked at uses a:visited to style links. Besides a:visited having higher specificity, shouldn't :visited be equivalent and simpler?
TL;DR: At the time of writing, you are completely correct; there is no difference between a:visited and :visited. However, using a:visited is best practice for future-proofing your code.
TL;DR EDIT: As of August 2016, the CSS4 Working Draft allows other tags to use :visited. There is now a functional difference between a:visited and :visited! Beware.
For web development languages today, specifically HTML5 and CSS3, you are right: there is functionally no difference between a:visited and :visited. Now, please take this with caution: web standards, elements, and user interface protocols are ever-evolving, meaning that in the future, it is possible that a new tag compatible with :visited may be introduced.
When :visited was introduced in CSS, the W3C CSS1 spec said:
In CSS1, anchor pseudo-classes have no effect on elements other than 'a'. Therefore, the element type can be omitted from the selector:
a:link { color: red } == :link { color: red }
HOWEVER, in the CSS2 spec, the behavior of the :visited pseudo-class was not restricted to just a tags:
The document language determines which elements are hyperlink source anchors. For example, in HTML4, the link pseudo-classes apply to a elements with an "href" attribute.
This means that it is up to the document language and browser to determine which elements are compatible with :visited. While the current industry standard states that for HTML, only a elements with an href attribute qualify, this may well change later down the line.
EDIT, August 2016: Looks like the CSS4 Working Draft has confirmed my suspicion; in the new spec, :visited can be used for other "link-like" elements, namely <area> and <link>. The spec says:
The :any-link pseudo-class represents an element that acts as the source anchor of a hyperlink. For example, in [HTML5], any <a>, <area>, or <link> elements with an href attribute are hyperlinks.
So <a>, <area>, and <link> are all treated as hyperlinks, and the spec says that :visited applies to all hyperlinks. So as of CSS4, you'll be better off including the a in a:visited.
According to Selectors Level 4 :visited applies to any hyperlink, which in HTML is the <a>, <area> and <link> elements when they have an href attribute.
A quick test for the link element shows that Firefox at least partially respects this:
Try http://jsfiddle.net/rfdzpjLo/4/ in FF or see below
link:before { content:attr(href); }
link { display:block; }
:visited { color: red; }
:link { color:green; }
<link href="http://stackoverflow.com/questions/27263128/why-not-visited-instead-of-avisited-for-links" />
<link href="example.net/lsjhuehbsi00ejjdus" />
Yes, but it won't be future compatible if a new tag is introduced that may be styled with :visited.
Closest proof I can find:
http://www.w3.org/TR/CSS21/selector.html#link-pseudo-classes
The document language determines which elements are hyperlink source anchors. For example, in HTML4, the link pseudo-classes apply to A elements with an "href" attribute. Thus, the following two CSS 2.1 declarations have similar effect:
a:link { color: red }
:link { color: red }
In theory it's the same for reasons already mentioned. On paper, a:visited vs :visited makes it explicit that the style only applies to anchors, and may potentially be faster: think of it as the browser needing to iterate through all a tags in the one hand side, and checking if :visited applies, vs doing the same for all tags in the DOM.
Imho though, the more important reason is that styles related to a tag, a pseudo-selector, a class and an identifier aren't necessarily applied in a consistent and predictable order from a browser to the next.
Suppose, for instance, this visited link:
<a id="foo" class="bar" href="...">visited link</a>
Then consider the following CSS:
#foo {
color: red;
}
.bar {
color: green;
}
:visited {
color: purple
}
There used to be a time where the link would appear red, green or purple depending on the browser. (Perhaps it's still the case; I haven't tested.) Because, some would treat #foo as more important than .bar (it's an ID vs a class) and both of these as more important than :visited for similar reasons. Some would treat #foo, .bar and :visited as if they had the same importance, as a property of the tag itself. Some might have treated #foo and .bar as equals but more important than :visited on grounds the latter is a mere pseudo class. And so forth.
Now, consider this CSS, which is the kind of stuff you might encounter in a stylesheet today:
a.bar {
color: green;
}
:visited {
color: purple
}
Even assuming that tags, ID, classes and pseudo classes are all treated equal, we still have a potential problem, in that a.bar can also be considered more specific than plain :visited by some browsers.
Ergo, you end up needing to specify a:visited in the declaration to ensure the behavior is consistent in all browsers -- and chances are there are still a few bad apples around that'll make you want to write a:visited, a.bar:visited just to be sure.
Once you've run into the problem a few times, force of habit kicks in and you'll end up always writing a:hover or a:visited.
:visited is a pseudo class selector used only for anchor link elements that matches when the href attribute of that anchor link has been visited in the past by this browser. It is meant to be useful feedback for a user, so they can tell the difference between links they have been to and links they have not.
REFERENCE
The syntax of a pseudo class is as follows
selector:pseudo-class {
property:value;
}
So you have to use a selector when using a pseudo class and since it supports only links, in this case, the selector would be a.

define pseudo class and pseudo element in same element

My question is really simple, just what i am trying to do is :hover, :after and :before , i want hover anf after to embed in same element, check out my css code:-
#sidebar .widget li a:before:hover, #sidebar .widget li a.active:before {
background-position: 65% 65.7%;
}
Here the element have an icon in :before which i cnt remove or modify, and also i want to have an hover effect on it...
Any solution for this, my console doesn't show the hovering effect?
Interesting question. If you're able to show us a working example we could probably be of more help.
However, in theory there's nothing wrong with what you're attempting to do (although not all browsers will like it: particularly IE8 and below).
The important thing to understand here is that :hover is a pseudo-class, whereas :before is a pseudo-element.
Here's a quick excerpt from the standard (with thanks to this answer previously on Stack Overflow):
Pseudo-classes are allowed anywhere in selectors while pseudo-elements
may only be appended after the last simple selector of the selector.
The mistake you're making is in your syntax: the order that you're appending them.
Try this instead:
#sidebar .widget li a:hover:before,
#sidebar .widget li a.active:before {
background-position: 65% 65.7%;
}
That should do as you wish. However this isn't going to give you great cross-browser coverage, it's not something that all browsers support of have implemented.
A better approach would be to:
reset the :before element to nothing (overwrite the styles you can't access);
use a non-repeated background image on the anchor instead (to display the image), and padding-left to give the indentation;
You can then switch the background-image in whatever fashion you see fit using :hover on the anchor in your CSS.
This will give you far better cross-browser compatibility.

Why does hover work for the one link but not for the other?

I have two links in my header from the class "menu_top", hence:
<a class="menu_top" href="adverteerders.html" >adverteerders</a>
<a class="menu_top" href="ondernemers.html" >ondernemers</a>
The corresponding css code is:
.menu_top {
font-size: 14px;
}
.menu_top:link {color: #404040;}
.menu_top:hover {color: #CC0033;}
.menu_top:visited {color: #404040;}
When I execute this code and hover my mouse on 'adverteerders' then the colour does not change. When I hover my mouse on 'ondernemers' then strangely it does change. So what I did was COPIED the exact code of ondernemers and then it seemed to work again. Now when I rewrite 'ondernemers' to 'adverteerders' then the doesn't work again. However when I type oadverteerders.html then the hover works.
What the hell is going on here?
The order of your CSS selectors matters. When an element matches multiple CSS selectors with the same specificity, the selector defined later overrides the earlier one(s).
So if you use the :visited pseudo-class after the :hover pseudo-class, then the :visited styles will take precedent over the :hover styles, overriding them where they conflict.
That's why you typically want to define your :hover and :active styles after :visited.

Should the cursor property be set in a rule with or without the :hover pseudo-class?

Say you, or I, have coded an HTML element...
<a id='hydrogen' href='#'>H</a>
...and some :hover CSS...
#hydrogen:hover {
background:red;
}
...and now we want to put a fancy hand cursor when hovering. There's two options for this:
apply to stateless element:
#hydrogen {
cursor:pointer;
}
or, apply to :hover state.
#hydrogen:hover {
color:red;
cursor:pointer;
}
My question: is there any reason(s) why one way is decisively better than the other?
...or is it tomato, tomato?
Compatibility: IE6 and below only recognize the :hover pseudo class on a elements.
They are both the same, provided you always want the pointer there, reguardless of hovering.
The :hover pseudo class will inherit cursor: pointer from its non hovered state.
I would prefer to put it on the normal selector, rather than :hover.
Both ways are equally good. However i would put it on the id itself as :hover does not work on ie6 or below if element is not an anchor. If you do not care about older versions of IE. Then both ways are correct.

Combining two selectors in CSS3

Is there anyway to combine two selectors? such as:
#div:hover:not(.class)
Edit:
I understand this work as I wrote. However, how can I achieve a "hover" effect for a "LI" element , but exclude the hover effect when the mouse is over a certain "DIV' inside the LI?
E.G.
<li>Hello <div id="#no-hover">Bye</div> </li>
I would like to get a hover effect for the li:
li:hover{ text-color:#CCC; }
but somehow exclude the hover effect when the mouse is over the #no-hover div.
Any ideas?
Based on your question edit, to maximize browser compatibility (I mean, why not if you can?) you can get away with not using CSS3 selectors at all. Try this, assuming black is the default text color:
li, li:hover div#no-hover {
color: #000;
}
li:hover {
color: #ccc;
}
Although you may want to use a class instead of an ID if you want to affect multiple elements with a no-hover classification. In which case you would do this instead for your first rule:
li, li:hover div.no-hover {
Either way, since selecting a descendant with its ancestor is more specific than selecting just the ancestor, assuming the same combinators on the ancestor it'll override the second rule even though that one comes later.
Update:
If you only want to have the hover effect not applying to Bye, then you can just create an extra hover rule for that and set the color explicitly (as other answers showed).
If the hover effect should not apply to the whole li element, then I think there is no way to do it. You needed some kind of parent selector, which does not exist in CSS.
Yes and it is fairly easy to try: http://jsfiddle.net/5vaUW/
(probably only works if your browser supports CSS3)
You might want to read more about CSS3 selectors, where you can find this:
A selector is a chain of one or more sequences of simple selectors separated by combinators. One pseudo-element may be appended to the last sequence of simple selectors in a selector.
A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.
A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
In css2, would be:
li:hover{
color:#CCC;
}
li:hover div{
color: #000;
}
For CSS3, I agree with Felix Kling.

Resources