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

鼠标悬停动画1秒后未重置至预悬停状态,该如何解决?

问题描述

为元素设置hover动画后,希望动画运行1秒自动重置至预悬停状态,但当前动画结束后会停留在keyframes的to状态。如何实现无需mouseout操作即可让元素恢复初始状态?

原代码

CSS

.box:hover {
  --border-size: 3px;
  --border-angle: 0turn;
  background-image: conic-gradient(
  from var(--border-angle),
  #ebe7ee,
  #d7d7ef 50%,
  #fff
),
conic-gradient(from var(--border-angle), transparent 20%, #08f, #f03);
  background-size: calc(100% - (var(--border-size) * 2))
  calc(100% - (var(--border-size) * 2)),
cover;
  background-position: center center;
  background-repeat: no-repeat;

  animation: bg-spin 1s linear forwards;
  @keyframes bg-spin {
to {
  --border-angle: 1turn;
}
  }
}

@property --border-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0turn;
}

HTML

<div class="box"></div>
解决方案

核心问题有两个:一是forwards关键字让动画停留在最后一帧;二是:hover伪类会在鼠标停留时持续生效,无法自动解除。要实现完整的预悬停状态重置,需结合JavaScript控制样式生命周期:

完整实现代码

CSS

/* 预悬停基础样式 */
.box {
  width: 200px;
  height: 200px;
  border: 1px solid #eee;
  transition: all 0.2s ease;
}

/* 动画触发类,替代原:hover伪类样式 */
.box.animate-spin {
  --border-size: 3px;
  --border-angle: 0turn;
  background-image: conic-gradient(
    from var(--border-angle),
    #ebe7ee,
    #d7d7ef 50%,
    #fff
  ),
  conic-gradient(from var(--border-angle), transparent 20%, #08f, #f03);
  background-size: calc(100% - (var(--border-size) * 2)) calc(100% - (var(--border-size) * 2)), cover;
  background-position: center center;
  background-repeat: no-repeat;

  animation: bg-spin 1s linear forwards;
}

@keyframes bg-spin {
  to {
    --border-angle: 1turn;
  }
}

@property --border-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0turn;
}

HTML

<div class="box"></div>

JavaScript

const box = document.querySelector('.box');

box.addEventListener('mouseenter', () => {
  box.classList.add('animate-spin');
  
  // 1秒后移除动画类,恢复预悬停状态
  setTimeout(() => {
    box.classList.remove('animate-spin');
  }, 1000);
});

// 监听动画结束事件,防止重复触发导致的状态异常
box.addEventListener('animationend', () => {
  box.classList.remove('animate-spin');
});

关键调整说明

  1. 替换:hover伪类:将原hover样式移至独立的.animate-spin类,避免鼠标停留时样式强制生效。
  2. 控制类生命周期:通过mouseenter触发动画类添加,setTimeout在1秒后移除类,实现自动重置。
  3. 异常处理:监听animationend事件,确保动画提前结束时也能及时重置样式。

简化版(仅重置旋转角度)

若只需让旋转角度回到初始值,但保留hover背景样式,可直接修改CSS去掉forwards关键字:

.box:hover {
  /* 其他样式不变 */
  animation: bg-spin 1s linear; /* 移除forwards */
}

此方式下动画结束后--border-angle会自动回到0turn,但hover背景会持续保留,仅适用于部分场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:22:48