admin管理员组文章数量:1355611
I have an element which I call back
covered by another element which I call front
.
Back
is set in CSS to change color on hover. Front
is set, when hovered, to disappear after a 1s
delay and the mouse pointer which was on Front
element now is on back element.
Front
disappears by setting height: 0
in JavaScript. After Front
disappears and the mouse ointer is hovering on Back
the browser doesn't rerender the hover effect on Back
which results in its color not being changed as it should.
When I try the same example by naturally removing Front
from the DOM it works fine. My app, though, requires I do this by setting height: 0
.
You can try it for yourselves in the following examples. You will see a red box and a blue box. Red is Front
and blue is Back
. When you move the mouse pointer to the red box, the red box's color changes to green
. When you move your mouse onto the blue box, after one second, it will disappear.
The point of the example is to show that after the blue box disappears, the mouse pointer now hovers on the red box and it should therefore bee green
.
In this example, the blue box is removed from the DOM pletely and it works as well as expected.
In this example, though, the blue box is to be removed by setting height: 0
. After disappearing, the red element won't bee green
until after I move the mouse.
Is there any way to force browser to rerender?
The problem persists in Google Chrome and Microsoft Edge. Firefox works good.
I have an element which I call back
covered by another element which I call front
.
Back
is set in CSS to change color on hover. Front
is set, when hovered, to disappear after a 1s
delay and the mouse pointer which was on Front
element now is on back element.
Front
disappears by setting height: 0
in JavaScript. After Front
disappears and the mouse ointer is hovering on Back
the browser doesn't rerender the hover effect on Back
which results in its color not being changed as it should.
When I try the same example by naturally removing Front
from the DOM it works fine. My app, though, requires I do this by setting height: 0
.
You can try it for yourselves in the following examples. You will see a red box and a blue box. Red is Front
and blue is Back
. When you move the mouse pointer to the red box, the red box's color changes to green
. When you move your mouse onto the blue box, after one second, it will disappear.
The point of the example is to show that after the blue box disappears, the mouse pointer now hovers on the red box and it should therefore bee green
.
In this example, the blue box is removed from the DOM pletely and it works as well as expected.
In this example, though, the blue box is to be removed by setting height: 0
. After disappearing, the red element won't bee green
until after I move the mouse.
Is there any way to force browser to rerender?
The problem persists in Google Chrome and Microsoft Edge. Firefox works good.
Share Improve this question edited Jul 17, 2016 at 13:59 Angel Politis 11.3k15 gold badges50 silver badges67 bronze badges asked Jul 10, 2016 at 10:19 MisazMisaz 3,9953 gold badges28 silver badges45 bronze badges5 Answers
Reset to default 6Instead of trying to force the browser to rerender, you can just add a class to foo
that will make it green when bar
disappears and then, it returns to normal on mouseleave
.
CSS:
#foo.hover, /* <- I just added this */
#foo:hover {
background-color: green;
}
JavaScript:
var
foo = document.getElementById("foo"),
bar = document.getElementById("bar");
/* Set the 'mouseenter' event for bar to set the height to 0 and & the 'hover' class. */
bar.onmouseenter = function() {
setTimeout(function() {
bar.style.height = 0;
foo.classList.add("hover");
}, 1000);
}
/* Set the 'mouseleave' event for bar to remove the 'hover' class. */
bar.onmouseleave = function() {
foo.classList.remove("hover");
}
Check out the following snippet for a visual representation.
Snippet:
/* --- JavaScript --- */
var
foo = document.getElementById("foo"),
bar = document.getElementById("bar");
/* Set the 'mouseenter' event for bar. */
bar.onmouseenter = function() {
setTimeout(function() {
/* Set the height to 0. */
bar.style.height = 0;
/* Add the 'hover' class. */
foo.classList.add("hover");
}, 1000);
}
/* Set the 'mouseleave' event for bar. */
bar.onmouseleave = function() {
/* Remove the 'hover' class. */
foo.classList.remove("hover");
}
/* --- CSS --- */
#foo {
width: 200px;
height: 200px;
background-color: red;
position: absolute;
top: 10px;
left: 15px;
}
#foo.hover,
#foo:hover {
background-color: green;
}
#bar {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
top: 100px;
left: 100px;
}
<!-- HTML -->
<div id = "foo"></div>
<div id = "bar"></div>
This really seems like a browser issue, there are some ways on how to force webkit to redraw. But I really wouldn't remend that for you. You can simply use bar.style.display = 'none';
instead of setting the height to zero. Has the same effect and everything works as expected. See this fiddle: https://jsfiddle/zkhorh38/4/.
It's possible to do it in CSS just by playing with the transition
property.
#foo {
width: 200px;
height: 200px;
background-color:red;
position: absolute;
top:10px;
left:15px;
z-index: 10;
}
#foo:hover {
background-color: green;
}
#bar {
width: 200px;
height: 200px;
background-color:blue;
position: absolute;
top:100px;
left:100px;
z-index: 20;
transition: all 1000000s;
}
#bar:hover {
transition: all 0.01s;
opacity: 0;
z-index: 1;
}
<div id="foo"></div>
<div id="bar"></div>
If back is pletely covered by front, you could set front.style['pointer-events'] = 'none'
in the onmouseenter
callback first to let the mouse activate back's :hover
rule before front disappears.
See modified working snippet.
This might be a browser issue, but there are some ways on how to force webkit to redraw. But I wouldn't remend that for you. You can simply use bar.style.display = 'none';
instead of setting the height to zero.
Another solution to force a redraw/repaint that works just fine:
sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';
**
To avoid flickering you may try 'inline-block'
, 'table'
or 'run-in'
instead of 'none'
, but this may have side-effects. Also, a timeout of 0 triggers a reflow just like querying offsetHeight does: sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
Try this it really works !
本文标签: javascriptCSS hover rerender after covering element height 0Stack Overflow
版权声明:本文标题:javascript - CSS :hover rerender after covering element height 0 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744002116a2574049.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论