You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么CSS :focus伪类实现的按钮按压动画仅能生效一次?

问题根源

:focus伪类的触发逻辑和按压交互的需求不匹配:

  • :focus是元素获得焦点后的持续状态:第一次点击元素时,元素从非聚焦状态切换到聚焦状态,状态变更会触发一次动画;后续只要不点击其他区域让元素失焦,无论点击多少次元素,它的聚焦状态都不会发生变化,浏览器不会重复执行绑定的动画,这就是动画仅首次生效的核心原因。
  • 浏览器原生适配按压交互的瞬时状态伪类是:active,每次元素被按下(鼠标按键未松开、触屏按压未抬起)时都会触发,不需要额外逻辑就能实现每次按压都播放动画的效果。
修正代码

只需要调整CSS的伪类绑定,补充平滑回弹的过渡即可,HTML结构无需改动:

.icon {
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 220px;
  width: 220px;
  margin: 15px 0px;
  background-color: #f2f3f7;
  box-shadow: 0.6rem 0.6rem 1.2rem #d2dce9, -0.5em -0.5em 1em #ffffff;
  border-radius: 3rem;
  overflow: hidden;
  /* 增加过渡实现松开按钮时的平滑回弹效果 */
  transition: box-shadow 0.2s ease-in-out;
}

.icon img {
  width: 86%;
  height: 86%;
  border-radius: 50%;
}

/* 将原绑定在:focus上的动画移到:active伪类 */
.icon:active {
  animation: pressbtn 0.2s ease-in-out forwards;
}

@keyframes pressbtn {
  0% {
    box-shadow: 0.6rem 0.6rem 1.2rem #d2dce9, -0.5em -0.5em 1em #ffffff;
  }
  100% {
    box-shadow: inset 0.6rem 0.6rem 1.2rem #d2dce9, inset -0.5em -0.5em 1em #ffffff;
  }
}

对应的HTML保持原有写法即可:

<a href="#" class="icon">
  <img src="https://about.twitter.com/content/dam/about-twitter/en/brand-toolkit/brand-download-img-1.jpg.twimg.1920.jpg">
</a>
补充说明
  • 原代码中动画结束状态设置为box-shadow: none会导致按压后按钮阴影直接消失,不符合新拟态按钮的按压反馈逻辑,修正后的代码调整了动画结束状态为内凹阴影,匹配常规按压交互的视觉效果。
  • 如果业务场景必须用:focus触发动画,需要通过JS在每次点击时先移除动画属性、再重设动画属性,强制浏览器重启动画,但这种方案需要额外写脚本,性能和维护性都不如直接用:active实现按压反馈,非必要不推荐。

内容的提问来源于stack exchange,提问作者Maggie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:12:23