I am trying to animate a hidden menu box to appear and slide down when the mouse is over the button. It works properly, but when adding the transition display:inline-block
-> display:none
-> display:inline-block
the transition disappears.
I already saw a few posts with solutions in jQuery, but none is pure JavaScript, if not for one using EventListener (that I was not able to apply to my case).
I tried to separate the JS in two functions, one to show the block, and and one to change the class. It did not work. One way would be to add something like an EventListener that would call a function after the display property is changed (just adding it in JS seems not sufficient). Any help is appreciated.
Here the code:
function overbutton(divname) {
element = document.getElementById(divname);
if (element.className == "menu_hidden menu_about") {
//element.style.display ="inline-block";
element.className = "menu_shown menu_about";
} else {
//element.style.display ="none";
element.className = "menu_hidden menu_about";
}
}
function onmenu(divname) {
//element.style.display ="inline-block";
element = document.getElementById(divname);
element.className = "menu_shown menu_about";
}
function outmenu(divname) {
//element.style.display ="none";
element = document.getElementById(divname);
element.className = "menu_hidden menu_about";
}
.menu_about {
background-color: white;
height: 100px;
width: 100px;
top: 20px;
left: 50px;
border-radius: 10px;
box-shadow: 0px 0px 10px #2B2B2B40;
-webkit-box-shadow: 0px 0px 10px #2B2B2B40;
-moz-box-shadow: 0px 0px 10px #2B2B2B40;
position: absolute;
padding: 20px;
}
.menu_hidden {
-webkit-transform: translate(0%, -5px);
transform: translate(0%, -5px);
transition: transform 0.3s;
-webkit-transition: -webkit-transform 0.3s;
}
.menu_shown {
-webkit-transform: translate(0%, 5px);
transform: translate(0%, 10px);
transition: transform 0.3s;
-webkit-transition: -webkit-transform 0.3s;
}
<div style="padding-left:100px">
<button onm ouseover="overbutton('about_menu_div')" onm ouseout="overbutton('about_menu_div')">
menu Button
</button>
<!-- add style="display:none;"-->
<div id="about_menu_div" onm ouseover="onmenu('about_menu_div')" onm ouseout="outmenu('about_menu_div')">
Menu
</div>
</div>
JSfiddle: https://jsfiddle.net/g0ktx574/
CodePudding user response:
No need for any JavaScript in this case. You can solve this by using CSS, and more specifically, the :hover
pseudo-class and the
adjacent sibling selector.
Also, the display
property cannot be animated. Instead use opacity
in combination with visibility
.
.wrapper {
position: relative;
}
.menu_about {
position: absolute;
top: 100%;
left: 0;
background-color: white;
height: 100px;
width: 100px;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px #2B2B2B40;
opacity: 0;
visibility: hidden;
transition-property: opacity visibility transform;
transition: 0.3s;
}
.button-menu:hover .menu_about,
.menu_about:hover {
opacity: 1;
visibility: visible;
transform: translate(0%, 5px);
}
<div >
<button >
menu Button
</button>
<div >
Menu
</div>
</div>
CodePudding user response:
With reference to the solution posted here Transition translate animation immediately after display block, I have modified your code accordingly. One thing to keep in mind is that you cannot animate display property. So the below solution makes use of setTimeout
function to achieve the start and end point of the transform property. I have also removed some css as well. You can have a look. You can adjust the transition timing, and transform property according to your need.
function overbutton(divname) {
element = document.getElementById(divname);
if (element.className == "menu_hidden menu_about") {
element.style.display ="inline-block";
element.className = "menu_shown menu_about";
element.style.transform = "translate(0%, 10px)";
element.style.transition = "transform .7s";
setTimeout(function() {
element.style.transform = 'translate(0%, 30px)';
element.style.transition = "transform .7s";
}, 0)
}else{
element.style.display ="none";
element.className = "menu_hidden menu_about";
}
}
function onmenu(divname) {
element.style.display ="inline-block";
element = document.getElementById(divname);
element.className = "menu_shown menu_about";
}
function outmenu(divname) {
element.style.display ="none";
element = document.getElementById(divname);
element.className = "menu_hidden menu_about";
}
.menu_about{
background-color:white;
height:100px;
width:100px;
top:20px;
left:50px;
border-radius: 10px;
box-shadow: 0px 0px 10px #2B2B2B40;
-webkit-box-shadow: 0px 0px 10px #2B2B2B40;
-moz-box-shadow: 0px 0px 10px #2B2B2B40;
position: absolute;
padding: 20px;
}
/* hide menu initially */
.menu_hidden {
display: none;
}
<div style="padding-left:100px">
<button onm ouseover="overbutton('about_menu_div')" onm ouseout="overbutton('about_menu_div')">
menu Button
</button>
<!-- add style="display:none;"-->
<div id="about_menu_div" onm ouseover="onmenu('about_menu_div')" onm ouseout="outmenu('about_menu_div')">
Menu
</div>
</div>