CSS 强制动画在点击、活动或焦点时完全完成?

CSS force animation to be fully completed on click, active or focus?

鉴于:

.button_focus, .button_active {
  width: 8rem;
  height: 5rem;
  background-color: #e4e7eb;
}

.button_focus:focus,
.button_active:active {
  animation-name: clickAnimation;
  animation-duration: 250ms;
  animation-timing-function: ease-in-out;
}

@KeyFrames clickAnimation {
    0.00% { background-color: #d5d7da; }
   14.29% { background-color: #ced0d3; }
   28.57% { background-color: #bbbbbb; }
   42.86% { background-color: #b1b2b3; }
   57.14% { background-color: #b1b2b3; }
   71.43% { background-color: #bbbbbb; }
   85.71% { background-color: #ced0d3; }
  100.00% { background-color: #d5d7da; } 
}
<div class="contianer">
  <button class="button_focus">
    focus
  </button>
  <button class="button_active">
    active
  </button>
</div>

我想找到一种方法能够垃圾点击按钮并且每次都能完全处理动画。目前,使用 :focus 伪 class,我需要点击按钮然后点击离开,以便在我再次点击按钮时重新初始化动画。

相反,如果我使用 :active 伪 class,动画会在每次连续点击时播放,但不会 完全 完成。我需要按下 250ms 按钮才能让动画完全完成。


SO上有几个关于这个问题的帖子,解决方案似乎是使用JS添加动画class然后删除它,但在大多数帖子中,问题涉及悬停。就我而言,这只是一次点击,所以我不明白如何添加动画 class 并在某些时候删除它。我想我只是一头雾水。

有没有人有任何想法或提示?

问题是焦点和活跃的伪 classes 有点太持久或太短暂' - 所以要摆脱 fous 用户必须离开并保持活跃他们必须继续按。

使用 JS 我们可以监听按钮的点击,添加一个 class 来设置动画。

我们会永久监听按钮上的 animationend 事件,当它被触发时,我们会删除 class。这样动画在完成之前不会 'disturbed' ,但是我们确实需要删除它以便在下一次点击时可以再次设置它(否则如果设置没有变化 CSS 认为完成了)。

const button = document.querySelector('.button_click');
button.addEventListener('click', function() {
  button.classList.add('clicked');
});
button.addEventListener('animationend', function() {
  button.classList.remove('clicked');
});
.button_click {
  width: 8rem;
  height: 5rem;
  background-color: #e4e7eb;
  animation-name: none;
}

.button_click.clicked {
  animation-name: clickAnimation;
  animation-duration: 250ms;
  animation-timing-function: ease-in-out;
}

@KeyFrames clickAnimation {
  0.00% {
    background-color: #d5d7da;
  }
  14.29% {
    background-color: #ced0d3;
  }
  28.57% {
    background-color: #bbbbbb;
  }
  42.86% {
    background-color: #b1b2b3;
  }
  57.14% {
    background-color: #b1b2b3;
  }
  71.43% {
    background-color: #bbbbbb;
  }
  85.71% {
    background-color: #ced0d3;
  }
  100.00% {
    background-color: #d5d7da;
  }
}
<div class="contianer">
  <button class="button_click">
    click me
  </button>
</div>