Search code examples
javascripthtmlcssbuttontransition

CSS Adding Second Transition


I have a button which when pressed a div would appear from the bottom, and this works with a transition which lasts 0.5 seconds. However, when the div transitions down to disappear it snaps down rather than transitioning smoothly. I have tried but was unable to come up with a way for my div to transition down the same way it transitioned up.

i = 0;

function focusInput() {
  document.getElementById("infoButton").focus();
}
function blurInput() {
  document.getElementById("infoButton").blur();
}

function check() {
  if (i == 0) {
      focusInput()
      i++;
  } else {
      blurInput()
      i--;
  }
}
html,
body {
  height: 100%;
  margin: 0;
  overflow-x: hidden;
}

/* Hide scrollbar for Chrome, Safari and Opera */
.example::-webkit-scrollbar {
  display: none;
}

/* Hide scrollbar for IE, Edge and Firefox */
.example {
  -ms-overflow-style: none; /* IE and Edge */
  scrollbar-width: none; /* Firefox */
}

body {
  width: 100vw;
  height: 100vh;
  margin: 0;
  background-color: #eeeeee;
}

.settings {
  float: left;
  width: 35%;
  margin-top: 5px;
  text-align: right;
}

.settings .infoButton img {
  margin-top: -15px;
  margin-left: -5px;
  width: 15px;
}

.settings .infoButton {
  height: 20px;
  width: 20px;
  margin-top: 5px;
}

.slide {
  text-align: left;
  z-index: 999;
  visibility: hidden;
  position: absolute;
  width: 100vw;
  height: 100px;
  left: 0;
  top: 100%;
  background-color: #161618;
  -webkit-transition: top 0.5s;
  transition: top 0.5s;
}

.infoButton:focus + .slide {
  visibility: visible;
  top: calc(100vh - 100px);
}
<div class="settings">
  <button id="infoButton" onclick="check()" class="infoButton"><img src="https://pics.freeicons.io/uploads/icons/png/7410416951552644391-512.png" alt="settings icon"></button>
  <div class="slide">
    <p>Hello</p>
  </div>
</div>

This is my pencode: https://codepen.io/D4SH13/pen/VwbwgZN

Thank you in advance!


Solution

  • Visibility toggles instantly, hence executing before any transitions. The .slider is visible before the animation, when it's supposed to scroll up, and it's hidden before the animation, when it's supposed to scroll down.

    Translations over top comes with a performance issue. I changed the change in height to transform: translateY instead.

    You can only animate properties that are numbers, like hexcolors and ... well, ordinary numbers. So I hide the .slider by changing it's opacity.

    The second parameter in opacity 1ms 0.5s is a delay of 0.5 seconds.

    I honestly suggest using another solution, because your .slider will be at the bottom of the page, and it's still clickable. So I added pointer-events: none when .slider isn't focused.

    I also corrected your javascript code, putting "var" in front of your declaration and changed i (now: sliderOpen) to a boolean.

    var sliderOpen = true;
    
    function focusInput() {
      document.getElementById("infoButton").focus();
    }
    function blurInput() {
      document.getElementById("infoButton").blur();
    }
    function check() {
      if (sliderOpen) {
          focusInput()
      } else {
          blurInput()
      }
    
      sliderOpen = !sliderOpen;
    }
    

    Also, you don't need that javascript code. The CSS is enough to toggle your .slider. So I removed it and everything still works.

    html,
    body {
      height: 100%;
      margin: 0;
      overflow-x: hidden;
    }
    
    /* Hide scrollbar for Chrome, Safari and Opera */
    .example::-webkit-scrollbar {
      display: none;
    }
    
    /* Hide scrollbar for IE, Edge and Firefox */
    .example {
      -ms-overflow-style: none; /* IE and Edge */
      scrollbar-width: none; /* Firefox */
    }
    
    body {
      width: 100vw;
      height: 100vh;
      margin: 0;
      background-color: #eeeeee;
    }
    
    .settings {
      float: left;
      width: 35%;
      margin-top: 5px;
      text-align: right;
    }
    
    .settings .infoButton img {
      margin-top: -15px;
      margin-left: -5px;
      width: 15px;
    }
    
    .settings .infoButton {
      height: 20px;
      width: 20px;
      margin-top: 5px;
    }
    
    .slide {
      text-align: left;
      z-index: 999;
      position: absolute;
      height: 100px;
      left: 0;  
      background-color: #161618;
    
      /* CHANGED or ADDED */
      bottom: 0;
      right: 0;
      transition: transform 0.5s, opacity 1ms 0.5s;
      transform: translateY(100%);
      opacity: 0;
      pointer-events: none;
    }
    
    .infoButton:focus + .slide {
      /* CHANGED or ADDED */
      opacity: 1;
      transform: translateY(0%);
      transition: transform 0.5s, opacity 1ms;
      pointer-events: auto;
    }
    <div class="settings">
      <button id="infoButton" class="infoButton"><img src="https://pics.freeicons.io/uploads/icons/png/7410416951552644391-512.png" alt="settings icon"></button>
      <div class="slide">
        <p>Hello</p>
      </div>
    </div>