The class of DIV is FIRST. I want to call class SECOND on hover. How can I do this?
I am using following code:
.first{
background:#F00;
}
.second{
background: #0F0;
}
<div class="first"> This is DIV</div>
You don't need to use an additional class, just add the additional style on hover using the pseudo-selector :hover
<style>
.first{
background:#F00;
}
.first:hover{
background: #0F0;
}
</style>
As i am very kind, i have added an example of how to do what you are asking in pure javascript also:
<style>
.first{
background:#F00;
}
.second{
background: #0F0;
}
</style>
<div class="first" onmouseover="change()" onmouseout="changeBack()"> This is DIV</div>
<script>
function change() {
var d = document.getElementsByClassName("first");
d[0].className += " second";
}
function changeBack() {
var d = document.getElementsByClassName("first");
d[0].className = "first";
}
</script>
Your above way is not correct to do what you are looking for.
Check the below to know how to do it.
Live demo
The HTML code:
<div class="first"> This is DIV</div>
The CSS Code:
.first{
background:#F00;
}
.first:hover{
background: #0F0;
cursor: pointer;
}
Explanation
You need to declare :hover to create hover effect. So instead of creating a new class, you need to add :hover i.e a pseudo class to the class where you want the hover to work. This will make the hover effect you are looking for.
Reference:
W3 Hover reference
Hope this helps.
You can style an element (with a certain class) when another one is hovered in a limited number of cases. Main constraint: the hovered element must be placed in HTML code before the styled one.
More about + and ~ the adjacent and general sibling combinators
.first{
background:#F00;
}
.second{
background-color: #0F0;
}
.first:hover ~ .second {
background-color: tomato;
}
.first:hover ~ .hello .second {
background-color: violet;
}
.hello {
background-color: beige;
}
.hello {
padding: 1rem;
}
<div class="first"> This is DIV</div>
<div> Some div</div>
<div class="second"> I've class .second</div>
<div class="hello">
<div class="second"> Child of a (following) sibling of .first</div>
</div>
Hover the first box to see the result
This is how you would do it in javascript.
document.getElementById('idOfElement') is getting element reference.
Adding an event on it. In your case, you need two events which is onmouseover and onmouseleave.
let first = document.getElementById('first'),
sec = document.getElementById('second');
first.onmouseover = () => {
sec.style.background = 'black';
}
first.onmouseleave = () => {
sec.style.background = 'red';
}
#first, #second {
height: 100px;
width: 100px;
background: red;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s linear;
}
<div id="first">first</div>
<div id="second">second</div>
You can also do this on css. However, this is limited. You can't get reference to your parent element and previous sibling elements. That's what I know. (correct me if I am wrong).
#first, #second {
height: 100px;
width: 100px;
background: red;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s linear;
}
#first:hover ~ #second {
background: black;
}
<div id="first">first</div>
<div id="second">second</div>
Hope it helps. Cheers
Related
Let's assume I don't have access to JavaScript and can only edit CSS.
I still should be able to define a transition such that when JS (that I don't control) inserts a new element into a flex container the container widens smoothly, right?
// For the purposes this demo (to make it useful for my actual challenge),
// the only "allowed" JS is JS that adds or deletes an item within the container.
function insertOrDeleteExtraElement() {
const div = document.getElementById("new");
if (div) {
div.parentNode.removeChild(div);
} else {
const newDiv = document.createElement('div');
newDiv.innerHTML = "Inserting or deleting this should transition the container's width smoothly, honoring the transition duration.";
newDiv.id = "new";
document.getElementById("container").appendChild(newDiv);
}
}
#container {
border: 2px dashed blue;
display: inline-flex;
flex-wrap: wrap;
max-width: 250px;
transition: all 1s;
}
input {
flex: 1 1 100px;
transition: all 1s;
}
#new {
flex: 1 1 100%;
display: block;
border: 1px solid red;
height: 120px;
transition: all 1s;
}
.old {
background: #ccc;
border: 1px solid black;
}
<button onclick="insertOrDeleteExtraElement();" style="font-size: 16px;">Click here</button>
<br/>
<div id="container">
<input type="text" value="old input" class="old"/>
<div class="old">old div</div>
</div>
How can I accomplish my goal with only CSS (no JavaScript or HTML changes)?
Similar questions in years past (such as Is it possible to animate flexbox inserts, removes, and item position?) have collected answers about how to define CSS transitions, but they all required JavaScript to add or remove class names of an element.
To clarify: I don't want JavaScript manipulating classList of any existing element. The only allowed JavaScript would be the actual insertion of a new element into the flexbox container, such as in my example here.
P.S. Also, I need the new element to be on its own line, which is why I'm using flex-wrap: wrap;.
You can do like below for the insertion. I doubt you will have luck with the deletion since CSS cannot the remove event to do something before.
// For the purposes this demo (to make it useful for my actual challenge),
// the only "allowed" JS is JS that adds or deletes an item within the container.
function insertOrDeleteExtraElement() {
const div = document.getElementById("new");
if (div) {
div.parentNode.removeChild(div);
} else {
const newDiv = document.createElement('div');
newDiv.innerHTML = "Inserting or deleting this should transition the container's width smoothly, honoring the transition duration.";
newDiv.id = "new";
document.getElementById("container").appendChild(newDiv);
}
}
#container {
border: 2px dashed blue;
display: inline-flex;
flex-wrap: wrap;
max-width: 250px;
transition: all 1s;
}
input {
flex: 1 1 100px;
transition: all 1s;
}
.old {
background: #ccc;
border: 1px solid black;
}
#new {
flex: 1 1 0;
border: 1px solid red;
animation:grow 1s forwards;
height:0;
flex-basis:0;
min-width:0;
overflow:hidden;
}
#keyframes grow {
to {
height:120px;
flex-basis:100%;
}
}
<button onclick="insertOrDeleteExtraElement();" style="font-size: 16px;">Click here</button>
<br/>
<div id="container">
<input type="text" value="old input" class="old"/>
<div class="old">old div</div>
</div>
I'm working on a userscript for a page, so I don't have control over the original HTML. Also, because of the way the page loads and the script works, for various reasons I can only use CSS modifications here, and the modifications can only be on page-level CSS (not per-element style attributes).
So, the issue is, there is a large a element that has a hierarchy of divs in it. I would like to disable pointer events only on one of the child divs, while leaving everything functioning as normal everywhere else on the a. For example:
const disableBottomPointerEventsStyle =
'.bottom { pointer-events: none; cursor: default; }';
$('#test').click(function () {
$('<style/>')
.attr('type', 'text/css')
.text(disableBottomPointerEventsStyle)
.appendTo(document.head);
$(this).toggle();
});
.link { display: flex; width: 10ex; height: 20ex; margin-bottom: 1ex; }
.wrapper { display: flex; flex-direction: column; }
.top { border: 1px solid red; }
.bottom { border: 1px solid blue; }
div { flex-grow: 1; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- example of page structure: -->
<a class="link" href="about:blank">
<div class="wrapper">
<div class="top"></div>
<div class="bottom"></div>
</div>
</a>
<!-- ========================== -->
<button id="test">Test</button>
In that example there is an a with some divs in it, and the goal is to disable pointer events only on the blue div on the bottom while leaving everything else as-is.
To use the example press the Test button; this will insert a style rule in the document. My current best attempt is the value of disableBottomPointerEventsStyle:
.bottom { pointer-events: none; cursor: default; }
This has no effect.
So my question is, is it possible to do this only by modifying a page-wide CSS rule and, if so, how?
Note that this is fundamentally a CSS question, the JavaScript is pretty much incidental here.
The secret is to disable natural a behaviour, and enable it in the child.
I used hardcode a.link - to minimise a risk of side effects.
Supported https://caniuse.com/?search=pointer-events - should be good.
.link { display: flex; width: 10ex; height: 20ex; margin-bottom: 1ex; }
.wrapper { display: flex; flex-direction: column; }
.top { border: 1px solid red; }
.bottom { border: 1px solid blue; }
div { flex-grow: 1; }
a.link{ pointer-events: none}
div.top{ pointer-events: auto}
<a class="link" href="about:blank">
<div class="wrapper">
<div class="top"></div>
<div class="bottom"></div>
</div>
</a>
i have an inline blocked div inside anchor
HTML:
<ul>
<li>
<a href="">simple
<div class='bar'>
</div>
</a>
</li>
</ul>
CSS:
.bar {
width: 25px;
height: 25px;
background-color: red;
display: inline-block;
}
.bar:hover {
background-color: blue;
}
I need to get hover effect on div while i hover the anchor, not only div.
Also, my case is a little bit more complicated, so i cant use something like
a:hover .bar {
background-color: blue;
}
Here is jsfiddle with code http://jsfiddle.net/zeL102wr/2/
Check this http://jsfiddle.net/zeL102wr/4/
Add a class to your <a> tag and use :hover on that
Example
HTML
<a class="hoveranchor" href="">simple
<div class='bar'>
</div>
</a>
CSS
.hoveranchor:hover > .bar {
background-color: blue;
}
This would apply the style to all elements with class="bar" which are direct descendent of elements with class="hoveranchor"
looks like it can't be done in some universal way. only by something like wrapping li to some class and using css
.baz a:hover .foo .hover {
opacity: 1;
}
.baz a:hover .foo .main {
opacity: 0;
}
Updated the fiddle http://jsfiddle.net/zeL102wr/17/
Since i use LESS, i made a function
.enable-foo-hover() {
&:hover {
.foo {
.main {
opacity: 0;
}
.hover {
opacity: 1;
}
}
}
}
and use it for the element from which i need to hover my construction. Thanks for your answers
Updated Css
ul li a:hover ,.bar:hover {
background-color: blue;
}
Demo
If you are fine with using jquery the following will work for you 'advanced' list items...
JQUERY
$(document).ready(function () {
$('.hoveranchor').mouseover(function (e) {
console.log($(this).children('.main'));
$(this).find('.main').addClass('hover');
$(this).find('.main').removeClass('main');
});
$('.hoveranchor').mouseout(function (e) {
console.log($(this).children('.main'));
$(this).find('.hover').addClass('main');
$(this).find('.hover').removeClass('hover');
});
});
Additionally you will need to:
add class='hoveranchor' to your anchor tags
Remove
Remove css for :hover
Change opacity of .hover to 1
Check it in action here: http://jsfiddle.net/zeL102wr/5/
Why does the background-color of .a does not change when I hover? .b?
CSS
.a {
color: red;
}
.b {
color: orange;
}
.b:hover .a {
background-color: blue;
}
HTML
<div id="wrap">
<div class="a">AAAA
<div class ="b">BBBB</div>
</div>
</div>
http://jsfiddle.net/2NEgt/323/
Because .a is not descendent or comes after/inside of .b which is condition to work for it
for example if you inverse it, since .b is descendent of .a, it will work
.a:hover .b {
background-color: blue;
}
You are trying to select .a when it's a child of .b in a hover state. This could never happen .a is the parent of .b.
Actually you are trying to change background of parent on child hover this would not possible as it's parent of b if you change b's background color on hover of a then it will work
.a:hover .b {
background-color: blue;
}
it's here
http://jsfiddle.net/u7tYE/
There is an error in your HTML also .a is not descendent
HTML:
<div id="wrap">
<div class="a">AAAA</div>
<div class ="b">BBBB</div>
</div>
CSS:
.a {
color: red;
}
.b {
color: orange;
}
.b:hover, .a:hover {
background-color: blue;
}
Just been playing about with pointer-events property in CSS.
I have a div that I want to be invisible to all mouse events, except for :hover.
So all click commands go through the div to the one below it, but the div can report whether the mouse is above it or not still.
Can anyone tell me if this can be done?
HTML:
<div class="layer" style="z-index:20; pointer-events:none;">Top layer</div>
<div class="layer" style="z-index:10;">Bottom layer</div>
CSS:
.layer {
position:absolute;
top:0px;
left:0px;
height:400px;
width:400px;
}
Hover only. It is very easy. No JS... Prevent link default action too.
a:hover {
color: red;
}
a:active {
pointer-events: none;
}
Link here
Edit:
supported in IE 11 and above
http://caniuse.com/#search=pointer-events
"Stealing" Xanco's answer but without that ugly, ugly jQuery.
Snippet: Notice DIVs are in reverse order
.layer {
position: absolute;
top: 0px;
left: 0px;
height: 400px;
width: 400px;
}
#bottomlayer {
z-index: 10
}
#toplayer {
z-index: 20;
pointer-events: none;
background-color: white;
display: none
}
#bottomlayer:hover~#toplayer {
display: block
}
<div id="bottomlayer" class="layer">Bottom layer</div>
<div id="toplayer" class="layer">Top layer</div>
I don't think it's possible to achieve your aims in CSS alone. However, as other contributors have mentioned, it's easy enough to do in JQuery. Here's how I've done it:
HTML
<div
id="toplayer"
class="layer"
style="
z-index: 20;
pointer-events: none;
background-color: white;
display: none;
"
>
Top layer
</div>
<div id="bottomlayer" class="layer" style="z-index: 10">Bottom layer</div>
CSS (unchanged)
.layer {
position:absolute;
top:0px;
left:0px;
height:400px;
width:400px;
}
JQuery
$(document).ready(function(){
$("#bottomlayer").hover(
function() {
$("#toplayer").css("display", "block");
},
function() {
$("#toplayer").css("display", "none");
}
);
});
Here's the JSFiddle: http://www.jsfiddle.net/ReZ9M
You can also detect hover on different element and apply styles to it's child, or using other css selectors like adjacent children, etc.
It depends on your case though.
On parent element hover. I did this:
.child {
pointer-events: none;
background-color: white;
}
.parent:hover > .child {
background-color: black;
}
Pure CSS solution to your request (the opacity property is there just to illustrate the need for the transitions):
.hoverOnly:hover {
pointer-events: none;
opacity: 0.1;
transition-delay: 0s;
}
.hoverOnly {
transition: ,5s all;
opacity: 0.75;
transition-delay: 2s;
}
What it does:
When the mouse enters the box, it triggers the :hover state. However, in that state, the pointer-events are disabled.
But if you do not set the transitions timers, the div will cancel the hover state when the mouse moves; the hover state will flicker while the mouse is moving inside the element. You can perceive this by using the code above with the opacity properties.
Setting a delay to the transition out of the hover state fixes it. The 2s value can be tweaked to suit your needs.
Credits to transitions tweak: patad on this answer.
Just pure css, doesn't need jquery:
div:hover {pointer-events: none}
div {pointer-events: auto}
I use the :hover pseudo-element of an equal-sized parent/container to simulate a hover over my overlay div, then set the overlay's pointer-events to none to pass through clicks to elements below.
let button = document.getElementById('woohoo-button');
button.onclick = () => console.log('woohoo!');
let overlay = document.getElementById('overlay');
overlay.onclick = () => console.log(`Better change my pointer-events property back to 'none'`);
#container {
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-color: green;
width: 300px;
height: 300px;
}
#overlay {
background-color: black;
width: 100%;
height: 100%;
opacity: 0;
z-index: 1;
/* Pass through clicks */
pointer-events: none;
}
/*
Set overlay hover style based on
:hover pseudo-element of its
container
*/
#container:hover #overlay {
opacity: 0.5;
}
#woohoo-button {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
}
<div id="container">
<div id="overlay"></div>
<button id="woohoo-button">
Click Me
</button>
</div>