鼠标悬停动画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'); });
关键调整说明
- 替换:hover伪类:将原hover样式移至独立的
.animate-spin类,避免鼠标停留时样式强制生效。 - 控制类生命周期:通过
mouseenter触发动画类添加,setTimeout在1秒后移除类,实现自动重置。 - 异常处理:监听
animationend事件,确保动画提前结束时也能及时重置样式。
简化版(仅重置旋转角度)
若只需让旋转角度回到初始值,但保留hover背景样式,可直接修改CSS去掉forwards关键字:
.box:hover { /* 其他样式不变 */ animation: bg-spin 1s linear; /* 移除forwards */ }
此方式下动画结束后--border-angle会自动回到0turn,但hover背景会持续保留,仅适用于部分场景。
内容的提问来源于stack exchange,提问作者ishandutta2007
相关产品推荐
相关产品推荐

