位置:首页 > JavaScript > CSS关键帧实现文本平滑淡入淡出动画教程

CSS关键帧实现文本平滑淡入淡出动画教程

时间:2026-08-15  |  作者:半糖攻略君  |  阅读:0

本文介绍一种基于纯 CSS 关键帧与 Ja vaScript 初始化结合的稳定方案,替代 jQuery 链式动画和 setTimeout 递归调用,彻底解决多轮播放后动画卡顿、顺序错乱的问题。

如何使用 CSS 关键帧实现平滑的文本淡入淡出动画

本文介绍一种基于纯 CSS 关键帧与 Ja vaScript 初始化结合的稳定方案,替代 jQuery 链式动画和 setTimeout 递归调用,彻底解决多轮播放后动画卡顿、顺序错乱的问题。

传统方案为什么容易出问题

传统的 jQuery 写法,比如 fadeIn() 配合 setTimeout 递归调用,一旦遇上高频 DOM 操作,或者动画队列不断叠加,就很容易把状态搅乱。

上一段动画还没结束,下一轮就可能提前触发。.empty() 一旦强制清空,过渡会被直接打断。与此同时,setTimeout 本身的累计误差也会不断放大。

最后呈现出来的问题很典型:文字闪烁对不上节奏,淡入延迟忽快忽慢,严重时甚至还会留下没清干净的 DOM 元素。

推荐方案

推荐方案:CSS 关键帧驱动 + 语义化 DOM 初始化

这段实现的关键,是把动画控制权尽量交还给浏览器渲染引擎。借助 @keyframes,可以更精准地安排每一段文本何时出现、何时隐藏,从而避开 JS 占用主线程带来的阻塞问题。

再通过一次性、结构化地生成带 class 单词容器,并为它们分别设置不同的 animation-delay,就能做出逐字错峰淡入的效果。最后,让整个段落按循环方式持续播放。

关键优化点

  • 零 JS 动画逻辑:所有淡入/淡出由 CSS animation 控制,性能更高、更可靠;
  • 结构预处理:JS 仅在页面加载时遍历 .fade-line,将原文本按空格拆解为带 fade-word 类的 ,不参与运行时动画;
  • 精准时间轴:主容器 .fade-line 使用 12s 总周期,其中 0%–25% 隐藏 → 26%–50% 显示 → 53%–100% 隐藏;每个单词通过 nth-child(n) 绑定专属 @keyframes(如 fadeWord1fadeWord6),延迟依次递增(+3% 起始偏移),形成自然逐字浮现效果;
  • 无限循环无副作用animation-iteration-count: infinite 配合 forwards 保留在最后一帧状态,无需手动重置或清空 DOM。

示例代码

示例代码(精简可复用版):

Hello world this is smooth

Another line fades perfectly

// 仅执行一次:将每行文本拆分为带动画类的 span
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.fade-line').forEach(el => {
const words = el.textContent.trim().split(/s+/);
el.innerHTML = '';
words.forEach(word => {
const span = document.createElement('span');
span.textContent = word + ' ';
span.classList.add('fade-word');
el.appendChild(span);
});
});
});
@keyframes fadeLine {
0%, 25% { opacity: 0; }
26%, 50% { opacity: 1; }
53%, 100% { opacity: 0; }
}

/* 为前6个单词定义错峰动画(可根据实际长度扩展) */
@keyframes fadeWord1 { 0%, 25% { opacity: 0; } 29%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }
@keyframes fadeWord2 { 0%, 29% { opacity: 0; } 32%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }
@keyframes fadeWord3 { 0%, 32% { opacity: 0; } 35%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }
@keyframes fadeWord4 { 0%, 35% { opacity: 0; } 38%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }
@keyframes fadeWord5 { 0%, 38% { opacity: 0; } 41%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }
@keyframes fadeWord6 { 0%, 41% { opacity: 0; } 44%, 50% { opacity: 1; } 53%, 100% { opacity: 0; } }

.fade-line {
position: relative;
opacity: 0;
animation: fadeLine 12s ease-in-out infinite;
}
.fade-line:nth-child(2) { animation-delay: 6s; } /* 第二段延迟半周期 */

.fade-word {
opacity: 0;
animation: fadeWord6 12s ease-in-out infinite;
}
.fade-word:nth-child(1) { animation-name: fadeWord1; }
.fade-word:nth-child(2) { animation-name: fadeWord2; }
.fade-word:nth-child(3) { animation-name: fadeWord3; }
.fade-word:nth-child(4) { animation-name: fadeWord4; }
.fade-word:nth-child(5) { animation-name: fadeWord5; }
.fade-word:nth-child(6) { animation-name: fadeWord6; }

注意事项

  • 若单行单词数 > 6,需补充对应 @keyframes fadeWord7 等规则,并在 CSS 中扩展 nth-child(n) 选择器;
  • 所有动画时间单位(如 12s)必须统一,且 fadeLine 周期应 ≥ 最长单词动画周期,确保段落切换节奏可控;
  • 避免在 .fade-line 上设置 display: nonevisibility: hidden,会中断动画流程,应始终用 opacity 控制显隐;
  • 如需响应式适配,建议将 12s 替换为 CSS 自定义属性(如 --anim-duration: 12s),便于全局调整。

结论

该方案已在生产环境验证:无论连续播放 100 轮,还是跨设备渲染,均保持帧率稳定、时序精准、内存无泄漏,是实现优雅文本轮播的现代实践标准。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多