most venerable sir
most venerable sir

Reputation: 669

My two CSS animations happen at the same time. How do make it so one only happens after the other is completely finished?

I have a sliding side menu bar. I made two of them. One with a menu icon you can click to close it and open the other menu bar with a close icon.

The problem is my JS code and also the CSS transition animation don't give enough time for one to close before the other start to expand. So the two menu bars meet in the middle and create a messy animation.

function closeIt(){
  document.getElementById('mysidenav').style.width='0px';
  document.getElementById('mysidenav2').style.width='20%';
}
function openIt(){
  document.getElementById('mysidenav').style.width='20%';
  document.getElementById('mysidenav2').style.width='0px';
}
*{
  margin:0;
  padding:0;
}
html,body{
  height:100%;
  width:100%;
}
.sidenav{
  height:100%;
  width:20%;
  background:#111;
  transition:1s;
  overflow-x:hidden;
}
.sidenav a{
  font-size:90px;
  color:#818181;
}
/*SECOND SIDE BAR*/
.sidenav2{
  height:100%;
  width:0%;
  background:#111;
  overflow-x:hidden;
  position:fixed;
  top:0;
  transition:1s;
}
.sidenav2 a {
  font-size:50px;
  color:#818181;
}
<div id='mysidenav'class='sidenav'>
  <a onclick='closeIt()'>&times<a>
</div>
    
<div id='mysidenav2'class='sidenav2'>
  <a onclick='openIt()'>&#9776<a>
</div>

Upvotes: 0

Views: 116

Answers (4)

Josh
Josh

Reputation: 1474

The most performant way to do this is with CSS. Add a transition-delay.

.sidenav2{
  transition-delay: 1s;
}

Upvotes: 1

Thomas
Thomas

Reputation: 181725

You need to set a delay on the transition:

transition-delay:1s;

The problem is that this will apply when opening and when closing. So to fix that, add and remove a CSS class instead of poking at the width directly:

.hidden-sidenav {
  width:0;
  transition-delay:0s;
}

In the example below, I've also added transition-timing-functions so the closing speeds up over time, and the opening slows down. And reduced the timings a bit. Looks nicer that way.

function closeIt(){
  document.getElementById('mysidenav').classList.add('hidden-sidenav');
  document.getElementById('mysidenav2').classList.remove('hidden-sidenav');
}
function openIt(){
  document.getElementById('mysidenav').classList.remove('hidden-sidenav');
  document.getElementById('mysidenav2').classList.add('hidden-sidenav');
}
*{
  margin:0;
  padding:0;
}
html,body{
  height:100%;
  width:100%;
}

.sidenav{
  height:100%;
  width:20%;
  background:#111;
  transition:0.4s;
  transition-delay:0.4s;
  transition-timing-function:ease-out;
  overflow-x:hidden;
}
.sidenav a{
  font-size:90px;
  color:#818181;
}
/*SECOND SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDDDDDDDDDDDDDDDDDDDDEEEEEEE BAR*/
.sidenav2{
  height:100%;
  width:20%; /* Changed to 20%: visible by default. */
  background:#111;
  overflow-x:hidden;
  position:fixed;
  top:0;
  transition:0.4s;
  transition-timing-function:ease-out;
  transition-delay:0.4s;
}
.sidenav2 a {
  font-size:50px;
  color:#818181;
}
.hidden-sidenav { /* Must come after .sidenav and .sidenav2 to override them. */
  transition-delay:0s;
  transition-timing-function:ease-in;
  width:0;
}
<div id='mysidenav'class='sidenav'>
  <a onclick='closeIt()'>&times<a>
</div>
    
<div id='mysidenav2'class='sidenav2 hidden-sidenav'>
  <a onclick='openIt()'>&#9776<a>
</div>

Upvotes: 5

Peter B
Peter B

Reputation: 24136

You can do it with setTimeout(), like this:

function closeIt() {
  document.getElementById('mysidenav').style.width = '0px';
  window.setTimeout(function() {
    document.getElementById('mysidenav2').style.width = '20%';
  }, 1000);
}

function openIt() {
  document.getElementById('mysidenav2').style.width = '0px';
  window.setTimeout(function() {
    document.getElementById('mysidenav').style.width = '20%';
  }, 1000);
}
* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
  width: 100%;
}

.sidenav {
  height: 100%;
  width: 20%;
  background: #111;
  transition: 1s;
  overflow-x: hidden;
}

.sidenav a {
  font-size: 90px;
  color: #818181;
}


/*SECOND SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDDDDDDDDDDDDDDDDDDDDEEEEEEE BAR*/

.sidenav2 {
  height: 100%;
  width: 0%;
  background: #111;
  overflow-x: hidden;
  position: fixed;
  top: 0;
  transition: 1s;
}

.sidenav2 a {
  font-size: 50px;
  color: #818181;
}
<div id='mysidenav' class='sidenav'>
  <a onclick='closeIt()'>&times<a>
</div>
    
<div id='mysidenav2'class='sidenav2'>
  <a onclick='openIt()'>&#9776<a>
</div>

Upvotes: 0

Sergey
Sergey

Reputation: 7682

function closeIt(){
  document.getElementById('mysidenav').style.width='0px';
  setTimeout(function () {
    document.getElementById('mysidenav2').style.width='20%';
  }, 1000);
}
function openIt(){
  document.getElementById('mysidenav2').style.width='0px';
  setTimeout(function () {
    document.getElementById('mysidenav').style.width='20%';
  }, 1000);
}
*{
  margin:0;
  padding:0;
}
html,body{
  height:100%;
  width:100%;
}

.sidenav{
  height:100%;
  width:20%;
  background:#111;
  transition:1s;
  overflow-x:hidden;
}
.sidenav a{
  font-size:90px;
  color:#818181;
}
/*SECOND SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDDDDDDDDDDDDDDDDDDDDEEEEEEE BAR*/
.sidenav2{
  height:100%;
  width:0%;
  background:#111;
  overflow-x:hidden;
  position:fixed;
  top:0;
  transition:1s;
}
.sidenav2 a {
  font-size:50px;
  color:#818181;
}
<div id='mysidenav'class='sidenav'>
  <a onclick='closeIt()'>&times<a>
</div>
    
<div id='mysidenav2'class='sidenav2'>
  <a onclick='openIt()'>&#9776<a>
</div>

Just add the setTimeout that is equal to your transition time.

Upvotes: 0

Related Questions