.class a:hover vs .class:hover a - css

Couldn't find an answer to something I've been wondering about.
Is there a difference between .class2 a:hover {} and .class2:hover a {}? Or a preference for one over the other?
I've been using .class2 a:hover {} to alter anchors on anchor hover (ie: anchor text color), but when I wanted to alter the div that held the anchor as well (ie: anchor color and div background-color both change on hover), I had to use .class2:hover a {} for it to work. In doing so, I got confused as to the difference because between the two as they are written so similarly.
Thanks!
EDIT
Edited the question to be more clear. Thanks for untwisting my brain :)

My understanding is this:
.class2 a:hover will target any hyperlink tags within .class2 elements when the a tags are hovered.
.class2:hover a will target any hyperlink a tags within .class2 elements when .class2 is hovered.
The distinction is which element you hover in order to change those styling rules.
Example:
.box{
background: red;
width: 50px;
height: 50px;
margin-bottom: 10px;
}
.case1 a:hover {
background: blue;
}
.case2:hover a {
background: green;
}
<html>
<body>
<div class="box case1">case 1</div>
<div class="box case2">case 2</div>
</body>
</html>
In this case, do you want to hover the .class2 element or the a?

.class2 a:hover {}
With the above, the style would only apply to a when the a element is hovered specifically, if the .class element has padding or other content, hovering over the other parts of the .class element will not trigger the hovered style for a
.class2:hover a {}
While the above will trigger the hover style for a if any part of the .class2 element is hovered (padding, content, etc..)
Working fiddle here.

Yes. There is a difference.
Behaviorally, there may not seem like a difference, but if you add a margin around your <a> tag, you might find that your first selector (.class2 a:hover {}) will stop working as indended.

.class:hover a selects the a link when any part of the class is hovered upon while .class a:hover selects the a link only when the a link is hovered upon

In class2:hover, you're activating the CSS class under all elements nested in the class. This includes if you wanted to add padding outside the border of your links.
In class2 a:hover, the CSS class is only activated when you're hovering specifically over the link. Otherwise, the class is ignored.
Hope this helps!

Related

Is it valid CSS to include an element after a pseudo class in a selector?

I was trying to create an effect when I hover over a list element and not the anchor tag. For example, doing this:
#wrapper ul.menu li:hover {
color: #ff0000;
}
This will not change my color because I have an anchor tag style nested deeper, so I tried this and it works:
#wrapper ul.menu li:hover a {
color: #ff0000;
}
but I'm not sure if it is valid CSS to select elements after pseudo classes.
Any number of pseudo-classes can appear in any part of a selector. You are given the freedom to style a sibling or a descendant or otherwise any element that isn't the one to which you're applying the pseudo-class, whatever that pseudo-class may be, according to your needs.

How to edit :After-Content() when hovering? [duplicate]

How can I write :hover and :visited condition for a:before?
I'm trying a:before:hover, but it's not working.
This depends on what you're actually trying to do.
If you simply wish to apply styles to a :before pseudo-element when the a element matches a pseudo-class, you need to write a:hover:before or a:visited:before instead. Notice the pseudo-element comes after the pseudo-class (and in fact, at the very end of the entire selector). Notice also that they are two different things; calling them both "pseudo-selectors" is going to confuse you once you run into syntax problems such as this one.
If you're writing CSS3, you can denote a pseudo-element with double colons to make this distinction clearer. Hence, a:hover::before and a:visited::before. But if you're developing for legacy browsers such as IE8 and older, then you can get away with using single colons just fine.
This specific order of pseudo-classes and pseudo-elements is stated in the spec:
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.
A pseudo-class is a simple selector. A pseudo-element, however, is not, even though it resembles a simple selector.
However, for user-action pseudo-classes such as :hover1, if you need this effect to apply only when the user interacts with the pseudo-element itself but not the a element, then this is not possible other than through some obscure layout-dependent workaround. As implied by the text, standard CSS pseudo-elements cannot currently have pseudo-classes. In that case, you will need to apply :hover to an actual child element instead of a pseudo-element.
1 Of course, this does not apply to link pseudo-classes such as :visited as in the question, since pseudo-elements aren't links.
Write a:hover::before instead of a::before:hover: example.
To change a menu link's text on mouseover (different language text on hover), here is the
jsfiddle example
HTML:
<a align="center" href="#"><span>kannada</span></a>
CSS:
span {
font-size: 12px;
}
a {
color: green;
}
a:hover span {
display: none;
}
a:hover:before {
color: red;
font-size: 24px;
content: "ಕನ್ನಡ";
}
Try to use .card-listing:hover::after, hover, and after using ::. It will work.
Or you can set pointer-events:none to your a element and pointer-event:all to your a:before element, and then add hover CSS to a element:
a{
pointer-events: none;
}
a:before{
pointer-events: all
}
a:hover:before{
background: blue;
}
BoltClock's answer is correct. The only thing I want to append is that if you want to only select the pseudo element, put in a span.
For example:
<li><span data-icon='u'></span> List Element </li>
instead of:
<li> data-icon='u' List Element</li>
This way you can simply say
ul [data-icon]:hover::before {color: #f7f7f7;}
which will only highlight the pseudo element, not the entire li element.
You can also restrict your action to just one class using the right pointed bracket (">"), as I have done in this code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
span {
font-size: 12px;
}
a {
color: green;
}
.test1>a:hover span {
display: none;
}
.test1>a:hover:before {
color: red;
content: "Apple";
}
</style>
</head>
<body>
<div class="test1">
<span>Google</span>
</div>
<div class="test2">
<span>Apple</span>
</div>
</body>
</html>
Note: The hover:before switch works only on the .test1 class

CSS selector: Style the first "a" inside a div

I am having trouble finding the correct CSS selector, the structure I have looks like this:
<div>
</div>
<div>
</div>
<div>
</div>
I would like to style the a element of the first div
I have tried with this selector but with no luck
div:first-child a{}
first-child should work absolutely well, you can try
div:nth-of-type(1) a { /* Or div:first-child a */
color: red;
}
The above selector will select all 1st div element and will apply color to all a which are inside 1st div
Demo
If you are willing to style 1st occurrence of a in every div tag than you need to use
div a:nth-of-type(1) { /* Or div a:first-child */
color: red;
}
Here every 1st a will be selected in every div tag
Last but not the least if you want to select 1st a only in 1st div than use the below selector
div:nth-of-type(1) a:nth-of-type(1) { /* Or div:first-child a:first-child */
color: red;
}
Note: If still the above selectors doesn't work, than the possibility
is either some rule is more specific than the rules you are declaring,
or !important is used somewhere, or (least chances) you are testing
on older browsers
Your own example is working too.
http://jsfiddle.net/7Pea3/
div:first-child a {
color: #f00;
}
The first div will be selected and all a recive the color #CCC. I don't understand why this isn't working.
div:first-child a {
color: #CCC;
}
Else test this solution, that selects the first div and styles the first a tag in the div:
div:first-child a:first-child(1) {
color: #CCC;
}
Else you have problems with the :first-child selector use the :nth-of-type({ number expression | odd | even }) selector.

Why CSS selectors on links are tricky with underline with hover?

Here are two examples based on this HTML.
<a href="#">
<div class="foo">
hello
<span class="bar">world</span>
</div>
</a>
In the first one, I make the link not underline on hover, then make a sub-portion of the link underline, and that works fine:
a {
text-decoration:none;
}
a:hover {
text-decoration: none;
}
a:hover .bar {
text-decoration: underline;
}
http://jsfiddle.net/3qPyX/1/
In the second, I now reverse the selectors so that the second word should be un-underlined. However, now something strange happens. The entire link remains underlined even though the selectors seem like they should remove underline from the second word. <-- (this is the question. why does this happen?)
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
text-decoration: none;
}
http://jsfiddle.net/EAmwt/
Can someone explain what's going wrong in the second example? Inspecting with Chrome shows the span.bar has a computed style of text-decoration:none.
Update: a few answers explaining how to get around the problem, which is great except that's not really my question. What I want to know is why is this behavior different than, say, bold? For instance, if I try the 2nd example with bold, I get the expected results: http://jsfiddle.net/3qPyX/4/
Explanation:
The problem is that some properties (like text-decoration) get drawn to the whole parent inline element, whereas others - like font styling (that get inherited) - get overriden by the children properties.
Just for illustration: simmilarly, if you set a background color to a parent element it will paint the background of the parent ... and you would have to set another color to a child to lay it over (default - transparent - will still show the parent style through), but if you set font-weight at a child it will apply to the text inside the child element and override the parent settings.
You can find more detailed stuff on the text-decoration property in the CSS Level 2 and Level 3 Specifications.
A simple solution
withot changing the markup, you could just display .bar as inline-block.
Like so:
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
display:inline-block;
}
And the inline-block breaks out of the inline/text styling of the parent anchor element =) And you can then style it independently:
DEMO
When you do the text-decoration it is applied to the entire line at once. So the a:hover .bar doesn't cause any effect, because the underline is not being applied in the .bar but on the a.
Here is the specification: http://www.w3.org/TR/CSS21/text.html#lining-striking-props
UPDATE! (As #Cam suggested) :
You need the add in separate elements the parts of your text: http://jsfiddle.net/3qPyX/5/
The CSS:
.foo, a:hover .bar, a {
text-decoration:none;
}
a:hover .foo {
text-decoration: underline;
}

Nesting CSS Styles or inheritance

I'm pretty new to using CSS beyond applying directly to each element. I'd like to know how I should be doing this. (simplified from my actual implementation, but relatively the same). Is it possible to inherit styles somehow?
I have 3 div classes defined, each positioning a div in my page. I've left out the css for these, but the style divide my page into 3 sections.
div.left{}
div.center{}
div.right{}
Now, when a user selects one of the divs, it's then highlighted, so I have css to highlight it.
div.lefthighlighted{}
div.centerhighlighted{}
div.righthighlighted{}
I have to now repeat all the styles from div.left{} to div.lefthighlighted{} and add the styles to highlight, and this has to be done for all three div styles I've defined.
OK, I also have a tags within all three of these divs that I want styled different from all other a tags in my application, but they will be the same for the highlightd divs. This is were things get crazy.
I end up with the following for left, center and right. The worst part of this is that all the a tag styling is the same for left, lefthighlighted, center, centerhighlighted, right and righthighlighted, but I can't figure out how to share all of this.
div.left a:link {}
div.left a:visited {}
div.left a:active {}
div.left a:hover {}
div.lefthighlighted a:link{}
div.lefthighlighted a:visited {}
div.lefthighlighted a:active {}
div.lefthighlighted a:hover {}
Keep in mind, I'm simply putting empty braces here, but in my stylesheet, I've got a bunch of styles defined. Is there a way to say
div.left a:link {
inherit div.right a:link;
or
use div.right a:link;
}
I'm finding myself copying and pasting all the same styles and only changing the class name or the parent class name.
Give the elements multiple classes.
<div class="left highlighted">
And then just include the changed properties in the div.highlighted rule-set.
You can group styles by using the , (commas) as a separator. Eg:
div.left a:link, div.right a:link {}
/*Newlines don't matter:*/
div.left a:link,
div.right a:link {}
Note that the following does not work as "expected":
/*Expecting to select all links under div.left or div.right*/
div.left, div.right a:link {/*FAIL*/}
Another note about inheritance. Elements inherit styles from their parents. When a new matching selector is encountered, the styles from the parent still apply, unless defined otherwise:
a:link, a:visited, a:active {
color: red;
font-size: 16px;
}
a:hover{
font-size: 20px; /*font-size changed, while the color is still red.*/
}

Resources