How to prevent CSS animation restart after transition?

Viewed 173

I have made a button which has a small tab that upon hovering over it expands to the side. It is there because I want the button to be draggable. So once the tab expands, you can grab it and drag the button around. Don't mind the broken icons, they are supposed to be there from font awesome pack.

However I wanted to inform user, that the small tab can be grabbed, so I made a little jiggle effect on idle that plays two times indicating, that the tab can expand. And once user hovers over it, it fully expands. However when user unhovers the tab, the animation starts again. I need the animation to start only when the page loads and occur exactly 2 times and never again. Why does the aniamtion start after the transition that is there on hover and what can I do to disallow it animating again? Is it possible without JS?

Here is my code

.insite-draggable {
  z-index: 10;
  position: fixed;
  left: 45px;
  bottom: 12px;
}

.insite-handle {
  position: absolute;
  left: -14px;
  bottom: 13px;
  transition: left 0.3s cubic-bezier(0.32, 1.85, 0.43, 0.43);
  animation: bounce 2s;
  animation-iteration-count: 2;
  animation-delay: 2s;
}

.insite-handle:before {
  content: "\f100";
  font-family: "Font Awesome 5 Free";
  font-style: normal;
  font-size: 16px;
  line-height: 16px;
  display: inline-block;
  background-color: #1ea2b1;
  cursor: move;
  color: #ffffff;
  height: 16px;
  width: 26px;
  padding: 3px 3px 3px 4px;
  border-radius: 7px 0px 0px 7px;
  border: 1px solid #1a8e9b;
  transition: padding-left 0.3s cubic-bezier(0.32, 1.85, 0.43, 0.43);
}

.insite-handle:hover {
  left: -27px;
  animation: step-end;

  &:before { 
    content: "\f0b2";
    padding-left: 5px; 
  }
}

@keyframes bounce {
  0% { left: -14px; }
  10% { left: -20px; }
  20% { left: -14px; }
  30% { left: -20px; }
  40% { left: -14px; }
  100% {left: -14px; }
}

.insite-btn {
  display: block;
  position: relative;
  top: auto;
  left: auto;
  bottom: auto;
  right: auto;
  font-family: 'BrixSansBold';
  font-style: italic;
  font-size: 0.875rem;
  line-height: 1rem;
  -ms-border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  -moz-background-clip: padding;
  -webkit-background-clip: padding-box;
  background-clip: padding-box;
  color: #b00402;
  border: none;
  margin: 10px 10px 10px auto;
  padding: 7px 10px 7px 34px;
  text-decoration: none;
  text-transform: none;
  box-shadow: #333333 1px 1px 10px;
  background-color: #e3e000;
}
<span class="insite-draggable">
 <i class="insite-handle"></i>
  <a class="insite-btn" href="#">Turn on</a>
</span>

1 Answers

I used CSS Variables with fallback.

var(--use-this-variable-if-exist, use this fallback if no variable);

Initially there is no --left value, so it uses fallbacks. When hover, set --left value as -27px. Thus, the keyframes are also updated.

.insite-draggable {
  z-index: 10;
  position: fixed;
  left: 45px;
  bottom: 12px;
}

.insite-handle {
  position: absolute;
  left: -14px;
  bottom: 13px;
  transition: left 0.3s cubic-bezier(0.32, 1.85, 0.43, 0.43);
  animation: bounce 2s;
  animation-iteration-count: 2;
  animation-delay: 2s;
}

.insite-handle:before {
  content: "\f100";
  font-family: "Font Awesome 5 Free";
  font-style: normal;
  font-size: 16px;
  line-height: 16px;
  display: inline-block;
  background-color: #1ea2b1;
  cursor: move;
  color: #ffffff;
  height: 16px;
  width: 26px;
  padding: 3px 3px 3px 4px;
  border-radius: 7px 0px 0px 7px;
  border: 1px solid #1a8e9b;
  transition: padding-left 0.3s cubic-bezier(0.32, 1.85, 0.43, 0.43);
}

.insite-handle:hover {
  left: -27px;
  --left: -27px;
  &:before {
    content: "\f0b2";
    padding-left: 5px;
  }
}

@keyframes bounce {
  0% {
    left: var(--left, -14px);
  }
  10% {
    left: var(--left, -20px);
  }
  20% {
    left: var(--left, -14px);
  }
  30% {
    left: var(--left, -20px);
  }
  40% {
    left: var(--left, -14px);
  }
  100% {
    left: var(--left, -14px);
  }
}

.insite-btn {
  display: block;
  position: relative;
  top: auto;
  left: auto;
  bottom: auto;
  right: auto;
  font-family: 'BrixSansBold';
  font-style: italic;
  font-size: 0.875rem;
  line-height: 1rem;
  -ms-border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
  -moz-background-clip: padding;
  -webkit-background-clip: padding-box;
  background-clip: padding-box;
  color: #b00402;
  border: none;
  margin: 10px 10px 10px auto;
  padding: 7px 10px 7px 34px;
  text-decoration: none;
  text-transform: none;
  box-shadow: #333333 1px 1px 10px;
  background-color: #e3e000;
}
<span class="insite-draggable">
 <i class="insite-handle"></i>
  <a class="insite-btn" href="#">Turn on</a>
</span>

Related