Search code examples
javascripthtmlcsspopuptoast

How do I prevent this element from Hiding and then showing up again?


I have a problem with the code below. What it is supposed to do is show a toast on page load. After 3500 milliseconds, it is supposed to disappear. It does that, then appears again, skips the fade out transition, and disappears. How do make it fade in, wait 3500 milliseconds, then fade out?

function showDonate() {
  var x = document.getElementById("snackbar");
  x.className = "show";
  setTimeout(function() {
    x.className = x.className.replace("show", "");
  }, 3300);
}

showDonate()
#snackbar {
  visibility: hidden;
  min-width: 250px;
  margin-left: 130px;
  background-color: #212529;
  color: #fff;
  text-align: right;
  border-radius: 2px;
  padding: 16px;
  position: fixed;
  z -index: 999;
  left: 50%;
  bottom: 30px;
  font-size: 17px;
}

#snackbar.show {
  visibility: visible;
  -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
  animation: fadein 0.5s, fadeout 0.5s 2.5s;
}

@-webkit-keyframes fadein {
  from {
    bottom: 0;
    opacity: 0;
  }
  to {
    bottom: 30px;
    opacity: 1;
  }
}

@keyframes fadein {
  from {
    bottom: 0;
    opacity: 0;
  }
  to {
    bottom: 30px;
    opacity: 1;
  }
}

@-webkit-keyframes fadeout {
  from {
    bottom: 30px;
    opacity: 1;
  }
  to {
    bottom: 0;
    opacity: 0;
  }
}

@keyframes fadeout {
  from {
    bottom: 30px;
    opacity: 1;
  }
  to {
    bottom: 0;
    opacity: 0;
  }
}
<div id="snackbar"> <b>Hey There!</b> Give us your money! <a href="#">Link</a></div>


Solution

  • Add forwards to the animation, it will retain the style values from the last keyframe when the animation ends, more information. I've also made some modifications to the class changing.

    Working example:

    function showDonate() {
      var x = document.getElementById("snackbar");
      x.classList.add("show");
      setTimeout(function() {
        x.classList.remove("show");
      }, 3300);
    }
    
    showDonate()
    #snackbar {
      opacity: 0;
      min-width: 250px;
      // margin-left: 130px;
      background-color: #212529;
      color: #fff;
      text-align: right;
      border-radius: 2px;
      padding: 16px;
      position: fixed;
      z -index: 999;
      // left: 50%;
      bottom: 30px;
      font-size: 17px;
    }
    
    #snackbar.show {
      opacity: 1;
      animation: fadein 0.5s, fadeout 0.5s 2.5s forwards;
    }
    
    @keyframes fadein {
      from {
        bottom: 0;
        opacity: 0;
      }
      to {
        bottom: 30px;
        opacity: 1;
      }
    }
    
    @keyframes fadeout {
      from {
        bottom: 30px;
        opacity: 1;
      }
      to {
        bottom: 0;
        opacity: 0;
      }
    }
    <div id="snackbar"> <b>Hey There!</b> Give us your money! <a href="#">Link</a></div>

    Update

    To change the length of the animation:

    1. Change the visible length in CSS (the number before forwards)
    2. Change the setTimeout length in JS (CSS in/out animation time + the number before forwards)

    For example if you want it to display for 5 seconds:

    • CSS: animation: fadein 0.5s, fadeout 0.5s 5s forwards;
    • JS: }, 5000+500+500);