skip to Main Content

I need to persist a hover state while animating a click.

When i hover the parent div the child should translate to -10px, I need to persist that translate -10px while the parent element is clicked and do a shake animation to the child element. But When i click the parent element the child lost it translate property and go back to its initial state and after the shake animation completes it going back to translate -10px.

I need to do the shake animation when the parent element click while persisting the translateY -10px.

Here is the demo.

.parent {
  width: 100px;
  height: 100px;
  background-color: red;
  display: flex;
  justify-content: center;
  align-items: center;
}
.child {
  width: 50px;
  height: 50px;
  background-color: green;
  transition: 1s ease;
}

.parent:hover .child {
  transform: translateY(-10px);
}
.parent:active .child {
  animation: shake 1s;
}

@keyframes shake {
  0% {
    transform: rotate(-10deg);
  }
  50% {
    transform: rotate(10deg);
  }
  100% {
    transform: rotate(0deg);
  }
}
<div class="parent">
    <div class="child"></div>
</div>

3

Answers


  1. .parent {
      width: 100px;
      height: 100px;
      background-color: red;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .child {
      width: 50px;
      height: 50px;
      background-color: green;
      transition: 1s ease;
    }
    
    .parent:hover .child {
      transform: translateY(-10px);
    }
    .parent:active .child {
      animation: shake 1s;
    }
    
    @keyframes shake {
      0% {
        transform: rotate(-10deg);
      }
      50% {
        transform: rotate(10deg);
      }
      100% {
        transform: rotate(0deg);
      }
    }
    <div class="parent">
        <div class="child"></div>
    </div>
    Login or Signup to reply.
  2. use margin-top: -10px insted transform: translateY(-10px)

    .parent {
      width: 100px;
      height: 100px;
      background-color: red;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .child {
      width: 50px;
      height: 50px;
      background-color: green;
      transition: 1s ease;
      position: relative;
    }
    
    .parent:hover .child {
      margin-top: -10px;
    }
    .parent:active .child {
      animation: shake 1s;
    }
    
    @keyframes shake {
      0% {
        transform: rotate(-10deg);
      }
      50% {
        transform: rotate(10deg);
      }
      100% {
        transform: rotate(0deg);
      }
    }
    <div class="parent">
        <div class="child"></div>
    </div>

    Or, You Can Use translateY(-10px) in your animation:

    @keyframes shake {
      0% {
        transform: translateY(-10px) rotate(-10deg);
      }
      50% {
        transform: translateY(-10px) rotate(10deg);
      }
      100% {
        transform: translateY(-10px) rotate(0deg);
      }
    }
    
    .parent {
      width: 100px;
      height: 100px;
      background-color: red;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .child {
      width: 50px;
      height: 50px;
      background-color: green;
      transition: 1s ease;
    }
    
    .parent:hover .child {
      transform: translateY(-10px);
    }
    .parent:active .child {
      animation: shake 1s;
    }
    
    @keyframes shake {
      0% {
        transform: translateY(-10px) rotate(-10deg);
      }
      50% {
        transform: translateY(-10px) rotate(10deg);
      }
      100% {
        transform: translateY(-10px) rotate(0deg);
      }
    }
    <div class="parent">
        <div class="child"></div>
    </div>
    Login or Signup to reply.
  3. One way to achieve this is by using the rotate property, instead of using the rotate built in to the transform property.

    This way, you simply don’t need to add transform: translateY(-10px) into the :active selector. Otherwise, you would have to declare translateY(-10px) into every keyframe of the animation.

    Keep in mind that if you hover and then click very fast, the box would jump from e.g. -2px to -10px. If you want to smoothe this out, you would need JavaScript to calculate the property value during the transition.

    .parent {
      width: 100px;
      height: 100px;
      background-color: red;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .child {
      width: 50px;
      height: 50px;
      background-color: green;
      transition: 1s ease;
    }
    
    .parent:hover .child {
      transform: translateY(-10px);
    }
    .parent:active .child {
      animation: shake 1s;
    }
    
    @keyframes shake {
      0% {
        rotate: -10deg;
        /* OR: transform: rotate(-10deg) translateY(-10px) */
      }
      50% {
        rotate: 10deg;
        /* OR: transform: rotate(10deg) translateY(-10px) */
      }
      100% {
        rotate: 0deg;
        /* OR: transform: rotate(0deg) translateY(-10px) */
      }
    }
    <div class="parent">
        <div class="child"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search