Can I make a certain element fade in when I hover over another one, and make it fade out when my mouse isn\'t on the element anymore?
I tried adding a transition
Here is a mostly css answer: http://jsfiddle.net/Z7GuR/4/
Instead of using display
since that has only two modes (in this case: none
and block
) you should use opacity
. That will give you a smooth transition.
Css:
#menu {
background-color: rgb(0,100,0);
width: 200px;
height: 100px;
margin-left: 50px;
// Notice
opacity: 0;
transition: opacity 1s;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;
-o-transition: opacity 1s;
}
Javascript:
function showMenu() {
document.getElementById("menu").style.opacity = 1;
}
function hideMenu() {
document.getElementById("menu").style.opacity = 0;
// If you want, you can bind an "end" event to css transition and
// set "display" to none when that happens
}
As some have pointed out, the element will still take up space even after its opacity is set to 0
. To prevent this, you can set display
to none
after the animation has ended, as I said in the example (sorry if this wasn't clear). This is much better than changing the margin
, which is a "hacky" solution.
Edit: Okay, the display: none
, works, but for some reason, with display: block
, the animation is choppy when you fade back in, if it's completely faded out previously (in chrome, at least). So, instead of display: none
, I used a combination of position: absolute
, and visibility: hidden
, to hide the element:
http://jsfiddle.net/Z7GuR/4/
var menu = document.getElementById("menu"), button = document.getElementById("button");
function showMenu() {
menu.style.opacity = 1;
// Reset visibility and position
menu.style.visibility = "visible";
menu.style.position = "static";
menu.removeEventListener("transitionend", setDisplayNone, false);
}
function hideMenu() {
menu.style.opacity = 0;
// I prefer using transitionend to setTimeout
// transitionend is more extendable, and it makes more sense to me
menu.addEventListener("transitionend", setDisplayNone, false);
}
function setDisplayNone() {
menu.style.visibility = "hidden";
menu.style.position = "absolute";
}
button.addEventListener("mouseover", showMenu);
button.addEventListener("mouseout", hideMenu);
The only major difference between my answer and the accepted answer is that the text will always be visible (the fading element won't cover it).
At first, I thought about soktinpk's solution. Opacity can be animated with css so it's the best bet.
However, it takes up the space even when it is not shown. To prevent that, you could make it position:absolute
. But even then, elements behind it will not be clickable.
To prevent that, hide it with when it is not visible.display:none
Actually, visibility:hidden
seems to work better when fading back in.
HTML
<div id="button" onmouseover="showMenu()" onmouseout="hideMenu()">
<!-- placing it inside will allow it to be positioned as wanted -->
<div id="menu"></div>
</div>
CSS
#button {
background-color: rgb(0,0,100);
width: 100px;
height: 50px;
margin-top: 50px;
margin-left: 50px;
position:relative; // All absolutely positioned elements inside are relative to this element
}
#menu {
background-color: rgb(0,100,0);
width: 200px;
height: 100px;
opacity:0;
visibility:hidden;
transition: opacity 1s;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;
-o-transition: opacity 1s;
position:absolute; // So that it displays at the right position
top:100%;
left:0;
}
JS
var time_out;
var menu = document.getElementById("menu");
function showMenu() {
clearTimeout(time_out);
menu.style.visibility = "visible";
menu.style.opacity = 1;
}
function hideMenu() {
clearTimeout(time_out);
menu.style.opacity = 0;
// This will hide it when the animation is over
time_out = setTimeout(function(){menu.style.visibility = "hidden";},1000);
}
JS Fiddle Demo
Here's a pure css solution for your specific html:
fiddle
<div id="button" onmouseover="showMenu()" onmouseout="hideMenu()"></div>
<div id="menu"></div>
for the css I used opacity instead of display and added the following:
#button:hover ~ #menu,
#menu:hover {
opacity:1;
height:100px;
}