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

如何实现CSS动画在页面加载与hover/out时均触发

实现方案

现有基于transition实现的hover动画依赖状态变化触发,要同时支持页面加载自动播放、hover触发两套场景且动画效果完全一致,最优实现是把动画核心逻辑抽离为公共@keyframes关键帧,配合极少量JS处理初始加载的一次性触发即可,全程不需要重复编写动画位移/旋转规则。

核心实现步骤

  • 抽离公共动画关键帧:把左右两个圆的位移、翻转效果定义为独立关键帧,桌面端、移动端分别匹配对应位移值,所有场景复用同一段动画定义
  • 修正原有CSS笔误:原代码中transition-timing为错误属性,替换为标准属性transition-timing-function保证缓动效果生效
  • 初始加载动画触发:DOM加载完成后给容器添加一次性动画类,动画执行完整的「移入-移出」往返流程,总时长和hover交互时长完全对齐,动画结束后移除该类,不影响后续hover交互
  • 保留原有hover交互逻辑:原有基于transition的hover效果不需要大幅修改,和关键帧动画终点状态完全对齐,不会出现样式跳变

完整实现代码

CSS部分

body {
  margin: 0;
  padding: 0;
}
.animation-design {
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  position: relative;
}
.left,
.right {
  width: 215px;
  height: 215px;
  border: solid 1.2px #4d4e53;
  border-radius: 50%;
}
.left {
  position: absolute;
  left: 0;
  top: 0;
}
.right {
  position: absolute;
  left: 100px;
  top: 100px;
}

.animation-design .left,
.animation-design .right {
  transition: all 3s;
  transition-timing-function: ease-in-out;
}

/* 公共动画关键帧定义 */
@keyframes moveFlipLeft {
  to {
    transform: translateX(100px) rotateY(180deg);
  }
}
@keyframes moveFlipRight {
  to {
    transform: translateX(-100px) rotateY(180deg);
  }
}

/* 页面加载时触发的一次性动画类 */
.load-animate .left {
  animation: moveFlipLeft 3s ease-in-out;
  animation-direction: alternate;
  animation-iteration-count: 2;
}
.load-animate .right {
  animation: moveFlipRight 3s ease-in-out;
  animation-direction: alternate;
  animation-iteration-count: 2;
}

.animation-design:hover .left {
  transform: translateX(100px) rotateY(180deg);
}
.animation-design:hover .right {
  transform: translateX(-100px) rotateY(180deg);
}

/******** 响应式适配 ***********/
@media (max-width: 568px) { 
  .animation-design {
    width: 132px;
    height: 132px;
  }
  .left, .right {
    width: 90px;
    height: 90px;
  }
  .right {
    position: absolute;
    left: 38px;
    top: 38px;
  }
  /* 移动端匹配对应动画参数 */
  @keyframes moveFlipLeft {
    to {
      transform: translateX(38px) rotateY(180deg);
    }
  }
  @keyframes moveFlipRight {
    to {
      transform: translateX(-38px) rotateY(180deg);
    }
  }

  .animation-design:hover .left {
    transform: translateX(38px) rotateY(180deg);
  }
  .animation-design:hover .right {
    transform: translateX(-38px) rotateY(180deg);
  }
}

JS部分

无需引入第三方库,仅需添加极短逻辑处理初始加载触发:

document.addEventListener('DOMContentLoaded', () => {
  const container = document.querySelector('.animation-design')
  container.classList.add('load-animate')
  // 动画总时长6s(3s去程+3s回程),跑完移除类名避免干扰后续hover交互
  setTimeout(() => {
    container.classList.remove('load-animate')
  }, 6000)
})

HTML部分

和原有代码完全一致,无需修改:

<body>
  <div class="animation-design">
    <div class="left"></div>
    <div class="right"></div>
  </div>
</body>

实现说明

该方案下初始加载动画和hover触发的动画参数完全一致,不会出现效果差异;动画结束后移除初始类的操作,能完全避免初始动画和后续hover的transition冲突,鼠标移入移出的交互逻辑和原有效果完全相同。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:51:21