I have an HTML menu element that I am currently animating using javascript and CSS. The menu's max-height is set to 0, with overflow: hidden.
<div class="menu">
The current CSS animation:
.menu {
-webkit-transition: max-height 0.4s ease;
-moz-transition: max-height 0.4s ease;
transition: max-height 0.4s ease;
}
In javascript, I am changing the menu max-height when a button is clicked.
This all works fine, except I would like to reveal the menu from the bottom to the top, instead of the top-down. Can this be done in simple CSS or JS?
I have an HTML menu element that I am currently animating using javascript and CSS. The menu's max-height is set to 0, with overflow: hidden.
<div class="menu">
The current CSS animation:
.menu {
-webkit-transition: max-height 0.4s ease;
-moz-transition: max-height 0.4s ease;
transition: max-height 0.4s ease;
}
In javascript, I am changing the menu max-height when a button is clicked.
This all works fine, except I would like to reveal the menu from the bottom to the top, instead of the top-down. Can this be done in simple CSS or JS?
Share Improve this question asked May 12, 2017 at 19:00 crestinglightcrestinglight 3313 gold badges5 silver badges14 bronze badges3 Answers
Reset to default 15You can transition scaleY()
instead, and use transform-origin
div {
transform-origin: 0 100%;
width: 100px;
height: 100px;
background: black;
transition: transform .5s;
transform: scaleY(0);
}
body:hover div {
transform: scaleY(1);
}
<div></div>
Michael already provided a very elegant solution but it has the problem of scaling all content.
I just want to provide another approach: When using position:absolute
, you can set bottom:0
to make it reveal from the bottom. I used height
in the demo, because it's a bit easier to get the dimension how you want them, but max-height generally works just as fine as well.
Advantage: content does not scale
Disadvantage: needs positioning and some fixed height declarations
Whatever works best for you.
.menu {
background:#bada55;
transition: all 0.4s ease;
height:0;
overflow:hidden;
position:absolute;
bottom:0;
width:100%;
}
.container:hover .menu {
height:30px;
}
.container{
position:relative;
border:1px solid red;
height:30px;
}
<div class="container">
<div class="menu">
Menu content
</div>
</div>
Another possibility is to simply animate the positioning. Here you just manipulate the top
to achieve the sliding effect.
.menu {
background: #bada55;
transition: all 0.4s ease;
overflow: hidden;
position: relative;
width: 100%;
padding:10px;
height:40px;
box-sizing:border-box;
top:100%;
}
.container:hover .menu {
top:0;
}
.container {
border: 1px solid red;
overflow:hidden;
height:40px;
}
<div class="container">
<div class="menu">
Menu content
</div>
</div>
You could use flexbox
. You would need to align it to the bottom using align-items: flex-end;
.
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
document.querySelector('.menu').classList.toggle('active');
});
.menu {
max-height: 0;
overflow: hidden;
-webkit-transition: max-height 1s ease;
-moz-transition: max-height 1s ease;
transition: max-height 1s ease;
background: #eee;
display: flex;
align-items: flex-end;
}
.menu.active {
max-height: 300px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
}
ul li {
}
<button>Toggle Menu</button>
<div class="menu">
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4 (last item)</li>
</ul>
</div>
For reference, here is how the menu works without the flexbox aligning:
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
document.querySelector('.menu').classList.toggle('active');
});
.menu {
max-height: 0;
overflow: hidden;
-webkit-transition: max-height 1s ease;
-moz-transition: max-height 1s ease;
transition: max-height 1s ease;
background: #eee;
}
.menu.active {
max-height: 300px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
}
<button>Toggle Menu</button>
<div class="menu">
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4 (last item)</li>
</ul>
</div>