I am practicing my css using the hover when I notice this problem when I hover on top the color will change to blue and the middle will change to color red but when I hover to middle the middle changes the color to red but the top remains.
I tried to add a !important to the middle:hover but it didn't work. I also remove the + sign but i think it will not work since it should be on the same div for that to work.
why does the hover not working for the top div when middle div is hovered?
HTML
<div class="top">
<p> HELLO WORLD </p>
</div>
<div class="middle">
<p> HELLO PEOPLE </p>
</div>
CSS
.top:hover + .middle {
color:red;
}
.top:hover {
color:blue;
}
.middle:hover {
color:red;
}
.middle:hover + .top {
color: blue;
}
FIDDLE HERE
You cannot select a parent element in CSS unfortunately. But JavaScript can be used to resolve this problem.
Check out this for more info on selectors...http://www.w3.org/TR/CSS21/selector.html
The CSS + selector is the next sibling selector. It doesn't work on previous siblings, similar to how you can't target a parent from a child. This is because CSS works Top-Bottom, (ie parent > child, next sibling etc) and not vice versa.
This article explains why CSS doesn't have a parent selector but same logic applies for the lack of previous sibling selectors.
tldr: Bottom-Up CSS selectors are not feasible because of their performance implications in browsers.
Related
I have some very simple HTML that looks like
<div id="parent">
Child
</div>
I want to style the parent when hovering over the parent and I want to style the child when hovering over the child. I never want both to be styled at the same time.
I tried various combinations of :hover and :not() selectors in SCSS. Googling didn't bring me far; most solutions I found just tell me how to style the parent when hovering over the child, which is the opposite of what I want.
I found this and this workaround, both from 2013, but I was wondering whether there is a better, more modern way to do this.
If you only intend to support modern, evergreen browsers that support :has, then you can style #parent based on the following conditions:
is hovered
does not have a hovered child
That translates to a selector of such: #parent:hover:not(:has(#child:hover)).
In the example below, the #parent is red only when it is hovered and not its child:
#parent:hover:not(:has(#child:hover)) {
background: red;
}
#child:hover {
background: green;
}
<div id="parent">
Child
</div>
I know that there does not exist a CSS parent selector, but is it possible to style a parenting element when hovering a child element without such a selector?
To give an example: consider a delete button that when hovered will highlight the element that is about to become deleted:
<div>
<p>Lorem ipsum ...</p>
<button>Delete</button>
</div>
By means of pure CSS, how to change the background color of this section when the mouse is over the button?
I know it is an old question, but I just managed to do so without a pseudo child (but a pseudo wrapper).
If you set the parent to be with no pointer-events, and then a child div with pointer-events set to auto, it works:)
Note that <img> tag (for example) doesn't do the trick.
Also remember to set pointer-events to auto for other children which have their own event listener, or otherwise they will lose their click functionality.
div.parent {
pointer-events: none;
}
div.child {
pointer-events: auto;
}
div.parent:hover {
background: yellow;
}
<div class="parent">
parent - you can hover over here and it won't trigger
<div class="child">hover over the child instead!</div>
</div>
Edit:
As Shadow Wizard kindly noted: it's worth to mention this won't work for IE10 and below. (Old versions of FF and Chrome too, see here)
Well, this question is asked many times before, and the short typical answer is: It cannot be done by pure CSS. It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
But in most circumstances where this effect is wished, like in the given example, there still is the possibility to use these cascading characteristics to reach the desired effect. Consider this pseudo markup:
<parent>
<sibling></sibling>
<child></child>
</parent>
The trick is to give the sibling the same size and position as the parent and to style the sibling instead of the parent. This will look like the parent is styled!
Now, how to style the sibling?
When the child is hovered, the parent is too, but the sibling is not. The same goes for the sibling. This concludes in three possible CSS selector paths for styling the sibling:
parent sibling { }
parent sibling:hover { }
parent:hover sibling { }
These different paths allow for some nice possibilities. For instance, unleashing this trick on the example in the question results in this fiddle:
div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}
Obviously, in most cases this trick depends on the use of absolute positioning to give the sibling the same size as the parent, ánd still let the child appear within the parent.
Sometimes it is necessary to use a more qualified selector path in order to select a specific element, as shown in this fiddle which implements the trick multiple times in a tree menu. Quite nice really.
Another, simpler "alternate" approach (to an old question)..
would be to place elements as siblings and use:
Adjacent Sibling Selector (+)
or
General Sibling Selector (~)
<div id="parent">
<!-- control should come before the target... think "cascading" ! -->
<button id="control">Hover Me!</button>
<div id="target">I'm hovered too!</div>
</div>
#parent {
position: relative;
height: 100px;
}
/* Move button control to bottom. */
#control {
position: absolute;
bottom: 0;
}
#control:hover ~ #target {
background: red;
}
Demo Fiddle here.
there is no CSS selector for selecting a parent of a selected child.
you could do it with JavaScript
As mentioned previously "there is no CSS selector for selecting a parent of a selected child".
So you either:
use a CSS hack as described in NGLN's answer
use javascript - along with jQuery most likely
Here is the example for the javascript/jQuery solution
On the javascript side:
$('#my-id-selector-00').on('mouseover', function(){
$(this).parent().addClass('is-hover');
}).on('mouseout', function(){
$(this).parent().removeClass('is-hover');
})
And on the CSS side, you'd have something like this:
.is-hover {
background-color: red;
}
In 2022:
This can be now achieved with CSS only, using the :has pseudo-class and the following expression:
div:has(button:hover) {}
Here's a snippet showcasing the original proposition:
div:has(button:hover) {
background-color: cyan;
}
<div>
<p>Lorem ipsum ...</p>
<button>Delete</button>
</div>
See browser support here. At the time of writing, all major browser support it—except Firefox, which still has a flawed experimental implementation.
This solution depends fully on the design, but if you have a parent div that you want to change the background on when hovering a child you can try to mimic the parent with a ::after / ::before.
<div class="item">
design <span class="icon-cross">x</span>
</div>
CSS:
.item {
background: blue;
border-radius: 10px;
position: relative;
z-index: 1;
}
.item span.icon-cross:hover::after {
background: DodgerBlue;
border-radius: 10px;
display: block;
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
content: "";
}
See a full fiddle example here
This is extremely easy to do in Sass! Don't delve into JavaScript for this. The & selector in sass does exactly this.
http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand
I am trying to get multiple effects on a single image hover to allow the best outcome with the least code possible. Note: I do not want jquery at all! CSS only (even 3).
So I have an image which will change on hover and at the same time cause a Div below the said image to change the background image as well (which is actually text, I just couldn't find a way to change the text so I tried the image) and with it all having the hover image on the IMG tag to have a link to the place I want.
So far I managed to get the image changed and the links working on the hover image with this:
CSS
.container
{
width: 1500px;
height: 400px;
}
.image a:hover .container
{
background-image: url('logo-tp-text.png');
}
HTML
<div class="image">
<a href="http://www.google.com">
<img src="logo-tp.png" onmouseover="this.src='logo-fb.png';" onmouseout="this.src='logo-tp.png';">
</a>
</div>
<div class="container"></div>
Now, as you much more experienced people than me can see, I have the image on IMG tag self onmouseovered and out to try and avoid complications on the CSS, which worked: it changes into the image I need (LOGO-FB) and reverts to LOGO-TP onmouseout, with the link working. However, it is not changing the .container background as expected on hover on the IMG tag (which is the A tag reference)
So, waiting for the beating: what am I doing wrong? Using FF 32 browser.
Css does not contains parent navigation selectors... Only descendant and following sibilings.
Since the .container div is a sibiling to the .image div, you could set the :hover pseudo to the div instead to the anchor:
.image:hover ~ .container {
background-image: url('logo-tp-text.png');
}
As ~ is a general sibiling selector.
More info here: MDN General sibiling selector
Also
If the html markup stays the same as you showed, I mean, if the .container remains as a immediate followed sibiling to the .image div, you can also use an Adjacent Sibiling Selector
.image:hover + .container {
background-image: url('logo-tp-text.png');
}
I want solution using only CSS
we have 3 circle here.
Whenever I perform mouse-over on circles with class Name Mycircle , the circle with class Name BigCircle should change to red color
html
<div class="BigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
CSS
.mycircle,.BigCircle{width:50px; height:50px; border-radius:30px; background-color:grey; margin:3px}
.mycircle:hover{background:yellow}
.mycircle:hover .BigCircle{background:red}
Here is the demo >http://jsfiddle.net/JGbDs/4/
Thanks in Advance
In your comments you state that you cannot re-arrange the elements, but you can add ones if required.
For that reason the general sibling combintor in the accepted answer is not suitable as the .bigCircle element would have to come after all of the .myCircle elements.
There is no perfect way of achieving this using only CSS but it is possible by adding a "parent" element and using one of the following CSS solutions:
Solution 1
When hovering on the parent element, the .bigCircle child element will be coloured red:
Working example: http://jsfiddle.net/CKRef/
HTML
<div class="parent">
<div class="bigCircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* Add float to parent to fit width to content */
.parent {
float: left;
clear: both;
}
.parent:hover > .bigCircle{
background: red;
}
The issue with this solution is that the .bigCircle element will be coloured red when you hover anywhere on the parent, not just on .myCircle. Adding the float reduces this effect - but if you hover just outside of the circle then the .bigCircle will still be red.
Solution 2
Using the parent element as a relative container, we can add a new element to the page using the after pseudo selector when a .myCircle element is hovered over:
Working example http://jsfiddle.net/CKRef/1/
HTML
<div class="parent">
<div class="mycircle"></div>
<div class="mycircle"></div>
<div class="mycircle"></div>
</div>
CSS
/* replaced .bigCircle with mycircle:hover::after */
.mycircle, .mycircle:hover::after {
....
}
.parent {
position: relative;
}
.mycircle:hover::after {
content: "";
background-color: red;
position: absolute;
top: 0;
left: 0;
margin-top: 0;
}
The imperfection with this solution is that we are targeting the position of the first child of the parent element, rather than the element with the class name .bigCircle. Also, the after pseudo selector is not supported in IE7.
No. That's not possible using just css. "Any sibling" selector is not there in css.
However, if you can move BigCircle to end, you can use general sibling combinator which can select successor siblings.
.mycircle:hover ~ .BigCircle{background:red}
I have this code.
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>
.myDiv div:nth-child(odd) {
color: red;
}
.myDiv div:nth-child(even) {
color: blue;
}
I see why it's not working. It's making every odd div within myDiv be red. What I want it to do is make every odd example of a div within myDiv be red. How can I write that?
Here's a JSFiddle.
There are a couple of problems here. The :nth-child is on the wrong element. The inner divs are always the first child, so the :nth-child(odd) selector works for both. Instead move to
.myDiv:nth-child(odd) div
...however this does not work either because of the <p>. A working solution with your sample is
.myDiv:nth-of-type(odd) div
http://jsfiddle.net/tvKRL/1/
NOTE that the nth-of-type only works because the .myDiv elements are all divs (it's based on the element, not the selector), so the selector ignores the <p>. If there can be another div between .myDivs I don't think any CSS will work for what you want to do.
You can't do this generically, for the reason given by Domenic. To put it simply: there's no selector that lets you filter an existing subset of matched elements.
On the off chance that among your p and div.myDiv siblings the only div elements are the ones with that class anyway, then you could use :nth-of-type() to have it look at those intermediate divs only:
div.myDiv:nth-of-type(odd) div {
color: red;
}
div.myDiv:nth-of-type(even) div {
color: blue;
}
Or if there are other divs without that class which should be excluded, then unless there is some sort of pattern in which they're laid out, you're out of luck.
This is not possible. There is no CSS selector that will do what you want, as you can see by perusing the complete list of selectors.
In general CSS selectors do not "reach out" to encompass elements above the DOM tree of the one selected. You are asking for something even more sophisticated than that, combining characteristics of parent elements with ordinal properties of the targeted elements, even though those targeted elements are distributed among entirely different places in the DOM tree.
Just applynth-childto the first member of the descendant selector, not the last one.
div:nth-of-type(odd) > div {
color: red;
}
div:nth-of-type(even) > div {
color: blue;
}
<div class="myDiv">
<div>
I want to be red.
</div>
</div>
<p>I'm some other content on the page</p>
<div class="myDiv">
<div>
I want to be blue.
</div>
</div>