纯CSS3实现Loading文字动效:从@keyframes到逐字跳动
简介一份基于CSS3 animation动画属性打造的纯CSS加载动效源码适用于网页加载过程中的文字提示场景。无需JavaScript参与即可实现文字的拆分、上下滚动与循环播放既降低页面资源消耗又让等待过程更具视觉吸引力适合前端开发者、交互设计师直接套用或学习动画参数配置。压缩包共7个文件包括3个CSS样式文件、2个JavaScript脚本、1个HTML页面及1个说明文档整体仅7KB。CSS文件分别控制字符拆分、单元格动画与整体布局JS脚本用于辅助文字切分及动效控制说明文档则提供用法与参数注释结构简洁、易于二次修改。目前已有281人学习浏览对于希望快速实现轻量级加载动效、或深入研究CSS3 animation八大子属性如animation-duration、animation-timing-function、animation-iteration-count的开发者来说是一份直观的参考示例。1. Loading 文字动效就该这么写纯 CSS3 的轻量实现页面在等接口的时候最尴尬的就是那块空白的区域。要么放一只默认的菊花转圈要么写一行“加载中…”干巴巴地杵在那里。这套纯 CSS3 的 Loading 文字动效解决的就是这个视觉空窗——不依赖任何 JavaScript 动画库靠 keyframes 和 animation-delay 让“加载中”几个字逐一跳动起来三十行上下的代码复制到一个 HTML 文件里就能直接跑。如果你平时收藏夹里堆了不少 JS 特效源码下载又想让页面多一点文字特效的质感这套方案值得拿来当模板。它适合两种人想快速给页面加一个轻量加载反馈的前端开发者以及初学 CSS3 动画、想弄懂逐字动画写法的新手。前者可以直接抄走后者能顺着关键帧和延迟参数把原理看明白。2. 技术选型为什么 keyframes animation-delay 能替代 JS 特效库2.1 先算一笔账用 JS 写 Loading 动效要付出什么常见的 JS 加载动画写法是用 setInterval 或 requestAnimationFrame 去修改文字的透明度或位移。这套看似简单实际要把动画帧的时间戳、元素的当前状态、循环的停止条件全部手动维护起来。很多 JS 常用代码库里的 Loading 组件动辄上百行还要考虑组件销毁时清理定时器不然页面切走之后动画还在后台跑白白吃 CPU。如果真的只为了“几个字跳一跳”这个效果这个成本就明显偏高了。纯 CSS3 方案没有定时器没有状态变量浏览器原生合成器接管动画的每一帧代码体积小一个数量级维护成本几乎为零。2.2 animation-delay 是实现“逐字错落”的核心机制逐字 Loading 动画的观感关键在于“错落”二字——所有文字不能同时动要像一个波浪一样依次起伏。纯 CSS 没有循环语句不能像 JS 那样对每个字做 for 循环处理怎么办答案是把每个文字放在独立的 span 标签里然后给每个 span 设置不同的 animation-delay。动画延迟节奏 第 1 个字 delay 0s 第 2 个字 delay 0.2s 第 3 个字 delay 0.4s 第 4 个字 delay 0.6s这样四个字虽然用的是同一套 keyframes但因为入场时间错开了呈现出来的效果就是逐个跳动的波浪感。实际项目中文字数量不固定常常写成一个通用公式第 N 个字的 delay N × stepstep 通常取 0.15s 到 0.3s数值越大波浪越明显数值越小越接近整体同时运动。2.3 关键帧节奏设计duration、easing 与 infinite 的搭配动画节奏由三个参数共同决定。animation-duration 决定一次完整运动的时长Loading 场景取 1.2s 到 1.8s 比较合适太快显得慌乱太慢会让用户觉得页面卡顿。animation-timing-function 用 ease-in-out 比 ease 或 linear 更舒服因为文字弹跳需要一个加速和减速的过程模拟真实的物理运动。iteration-count 设为 infinite让动画循环播放。这里有一个细节keyframes 里定义的 0% 和 100% 状态要尽量一致否则每一轮循环结束到下一轮开始的瞬间会出现肉眼可见的“跳变”。比如 0% 是透明度 0.3100% 也必须是透明度 0.3而不是 50% 的完全不透明状态。keyframes loadingText { 0%, 100% { opacity: 0.3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-6px); } }这个关键帧把 opacity 和 transform 叠在一起写0% 和 100% 共用同一组状态50% 是整个动画的峰值——文字跳到最高点并且完全不透明。浏览器会自动补全中间的过程不需要你手动去算每一帧的具体位置。注意 transform 用 translateY 而不是 margin-top 或者 top 位移。translateY 走的是合成器线程不触发重排margin-top 变化会强迫浏览器重新计算布局移动端低端机上能明显感觉到掉帧。3. 核心代码拆解从 span 包裹到关键帧定义3.1 HTML 结构为什么必须逐字包裹div classloading span加/span span载/span span中/span span…/span /div这段 HTML 是整套动效的基础。四个 span 分别包裹四个字符每个 span 是独立的动画作用对象。如果不拆开直接写“加载中…”一整段文字CSS 动画只能让这段文字整体运动无法实现逐字错落的波浪效果。这里有两个可调整的点。第一文字内容按需替换比如“请稍候”“努力加载中”都可以字符数量变了以后只需要增删 span 标签动画会自动适配——前提是下面要讲的 nth-child 延迟规则也要跟着增删。第二省略号“…”单独占一个 span实际动画中它会和前面的字一起跳动替代了常见的“三个点轮流闪现”做法写法更干净。3.2 容器样式让文字始终居中显示.loading { display: flex; justify-content: center; align-items: center; min-height: 100vh; font-size: 42px; font-weight: 600; color: #333; }容器用 flex 布局justify-content 和 align-items 都设成 center这样无论屏幕尺寸怎么变文字永远在可视区域正中间。min-height: 100vh 保证了撑满整个视口页面单独打开这个 HTML 时能看到完整的居中效果。font-size 用 42px 是演示环境的默认值实际项目里建议改成相对单位比如 clamp(24px, 5vw, 48px)让文字在手机和桌面显示器上等比缩放。color 也可以换成你品牌色或者干脆去掉颜色设置跟随页面现有样式。3.3 动画样式transform 生效的关键一步.loading span { display: inline-block; animation: loadingText 1.6s ease-in-out infinite; }给每个 span 设置了 display: inline-block这一步是整个动画能不能跑起来的分水岭。span 默认是行内元素行内元素不响应 transform 和 opacity 之外的很多交互动效尤其是位移类变换经常直接失效。改成 inline-block 之后每个字变成一个独立的块级盒子transform 才能正常作用。animation 是简写属性顺序有讲究动画名称 loadingText、持续时间 1.6s、缓动函数 ease-in-out、循环次数 infinite。这个顺序写错了浏览器也能解析但如果你在后面追加第五个参数 animation-delay一定要先确认前面四个参数的位置没写错否则 delay 可能被浏览器当成无效值丢弃。3.4 逐字延迟nth-child 控制每个字的入场时机.loading span:nth-child(1) { animation-delay: 0s; } .loading span:nth-child(2) { animation-delay: 0.25s; } .loading span:nth-child(3) { animation-delay: 0.5s; } .loading span:nth-child(4) { animation-delay: 0.75s; }nth-child 选择器按位置匹配每个 span然后单独覆盖 animation-delay。这里的间隔 0.25s 配合 1.6s 的 duration波浪感最明显。数值改小到 0.1s四个字几乎同时运动效果接近整体跳动改大到 0.4s每一轮的间隔会拉得很长看起来像“一个字动完下一个才动”就不是波浪而是接力了。想让“加载中…”后面那三个点依次闪烁也可以在这里做文章把省略号三个点分别放进三个 span然后把动画名称从 loadingText 换成另一个只改 opacity 的关键帧。3.5 最终拼接一份可以直接保存的完整代码!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title纯CSS3 Loading文字加载动效/title style .loading { display: flex; justify-content: center; align-items: center; min-height: 100vh; font-size: 42px; font-weight: 600; color: #333; } .loading span { display: inline-block; animation: loadingText 1.6s ease-in-out infinite; } .loading span:nth-child(1) { animation-delay: 0s; } .loading span:nth-child(2) { animation-delay: 0.25s; } .loading span:nth-child(3) { animation-delay: 0.5s; } .loading span:nth-child(4) { animation-delay: 0.75s; } keyframes loadingText { 0%, 100% { opacity: 0.3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-6px); } } /style /head body div classloading span加/span span载/span span中/span span…/span /div /body /html完整 HTML 文件就这么长没有外部依赖、没有 JavaScript、没有网络请求。把这段代码存成 .html 文件双击用浏览器打开就是成品效果。如果你加到现有页面上只需要保留 .loading 的样式部分去掉 min-height: 100vh 和 flex 居中改成适配你项目容器的方式即可。参数取值作用animation-duration1.6s单次动画时长影响整体节奏animation-delay0.25s 递增控制逐字错落间隔translateY-6px文字弹跳高度越大跳得越高opacity0.3 / 1最低淡出程度与高亮程度4. 踩坑排查五种真机上让人摸不着头脑的加载动画问题4.1 动画一点反应都没有字纹丝不动现象代码照抄浏览器打开后“加载中…”几个字静态显示没有任何动画效果。原因九成是 span 还是行内元素。拷贝代码的时候如果漏掉了 .loading span 里的 display: inline-blocktransform: translateY 在行内元素上就是不生效。还有一种情况是直接给 .loading 加了 animation而不是给 .loading span 加——整段文字整体动了反而掩盖了问题或者干脆没动。解决先确认 display: inline-block 写在样式里再确认 animation 挂在 span 选择器上。用 DevTools 检查 span 的计算样式animation 名称和 duration 有没有被其他样式覆盖掉。4.2 四个字同时跳动没有错落感现象动画在跑但四个字像绑在一起一样同起同落。原因animation-delay 没有生效。常见的低级错误是写 animation 简写属性时把 delay 放在了 duration 的位置比如 animation: loadingText 0.25s ease-in-out infinite浏览器会把第一个数值当成 duration 而不是 delay。另一种可能是 nth-child 的写法和 HTML 结构不匹配比如 HTML 里 span 外面还套了别的标签导致 nth-child 匹配到了错误的元素。解决把 delay 单独写成一行不要混进简写属性里。检查 HTML 层级确保 .loading 的直接子元素就是 span中间不要插入注释节点或者包裹层。4.3 页面刚打开时文字闪一下高亮现象动画开始前所有字先以完全不透明的状态显示一瞬间然后才进入淡出跳动的循环。原因animation-delay 这段时间里元素还没有套用关键帧里的样式所以显示的是 CSS 里设置的默认 color 和默认 opacity: 1。延迟时间越长这个“闪一下”越明显。解决把 animation-fill-mode 设为 backwards让元素在动画延迟阶段直接应用第一帧的样式.loading span { animation: loadingText 1.6s ease-in-out infinite backwards; }这个属性让动画开始前和结束后都保持第一帧的状态视觉上从一进页面就是“未高亮”的状态没有闪变。4.4 渐变颜色文字在部分浏览器上直接变白现象有人喜欢把文字做成渐变效果用 background: linear-gradient 加 background-clip: text结果某几个浏览器里文字完全看不到。原因background-clip: text 的兼容性需要 -webkit- 前缀漏掉前缀时浏览器不支持该属性背景图整个盖在文字层上看起来就是一团模糊的渐变块文字被盖没了。解决先写带 -webkit- 前缀的版本再写标准版本。如果使用场景是普通 Loading 文字建议直接放弃渐变用纯色加 opacity 过渡最稳毕竟重点在“跳动”而不是“颜色”。4.5 动画在手机端掉帧严重现象桌面浏览器流畅切到低端安卓手机上就出现卡顿和丢帧。原因动画里用了 filter 或 animated property 过多。filter: blur 这类效果会触发昂贵的渲染开销transform 和 opacity 虽然走合成器线程但如果同时动画的属性太多主线程和合成线程之间的同步也会拖慢帧率。解决除 transform 和 opacity 之外不要同时动画其他属性。如果非要模糊效果可以把一次 blur 动画改成 opacity 渐入视觉差距很小性能差距巨大。5. 二次开发把 Demo 参数化成三个可复用的加载文字组件5.1 用 CSS 变量抽离关键参数直接抄代码能跑但每换一个项目就要去改 animation-delay 的具体数值慢慢就乱了。用 CSS 变量把节奏控制抽出来一行就能调完整套动画.loading { --duration: 1.6s; --step: 0.25s; --distance: -6px; } .loading span { display: inline-block; animation: loadingText var(--duration) ease-in-out infinite; animation-delay: calc(var(--step) * (var(--i) - 1)); }配合行内变量给每个 span 编号div classloading span style--i: 1加/span span style--i: 2载/span span style--i: 3中/span span style--i: 4…/span /div改造之后调整 --step 就能控制波浪的疏密程度调整 --distance 就能改变跳起的高度。新增文字的时候只需要复制一行 span 并把 --i 加一不用再碰 nth-child 规则。如果文字内容是动态的也可以在 JS 循环渲染时顺手输出这个变量。5.2 在不改变纯 CSS 性质的前提下做动画变体同样的 DOM 结构只要换一套 keyframes就能做出完全不同的效果。比如把 translateY 跳动改成透明度呼吸文字从几乎看不见慢慢亮起再淡出适合数据加载时间较长时使用观感更安静——把 loadingText 里 50% 那一段的 translateY(0) 保留opacity 改成 0.15 到 1 的渐变即可。做“进度百分比”动效时数字固定为 100把关键帧改成从 0 到 100 的数字滚动keyframes progressCount { 0% { content: 0; } 100% { content: 100; } }注意 content 不能直接动画这套方案需要用 ::before 配合 steps(11) 逐帧切换在实际项目里更推荐让后端接口返回进度值前端只负责更新数字节点纯 CSS 的百分比播放更多用于无后端参与的本地演示场景。5.3 接入框架动态渲染后动画如何重启如果项目的加载文字是动态出现的比如从接口返回错误信息后显示“加载失败”再用同一套动画去渲染会遇到动画不重启的问题——因为 CSS 动画只认同一元素的同名动画DOM 复用时浏览器觉得动画状态没变不会重新播放。解决思路是给元素换一个不同的动画名称来强制覆盖或者在插入动画节点前先移除再重新插入 DOM。我一般会在动态渲染的代码里主动清除旧节点const container document.querySelector(.loading); container.replaceChildren(...newSpans);这样每个新生成的 span 都是一次全新挂载动画状态自然从头开始。从那以后我每次写完一个带动画的组件都会顺手检查一遍“如果数据更新了动画到底会不会重启”已经成了肌肉记忆。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

LangChain+Ollama搭建完全离线AI助手:本地部署与RAG实践指南

LangChain+Ollama搭建完全离线AI助手:本地部署与RAG实践指南

今天是我给自用AI助手“断奶”的第19天。前18天功能全靠云端模型接口,能用是能用,但心里一直不踏实。直到有一次给同事演示内部资料问答,网络一抖,整屏白掉,当场翻车,我下定决心:把模型彻底搬到…

2026/10/18 12:16:19 阅读更多 →
ChatGPT辅助开发实战:从提示词工程到代码审查

ChatGPT辅助开发实战:从提示词工程到代码审查

1. 先从一句话说起:ChatGPT在开发流程里到底该站在哪个位置这几年我一直在折腾各种开发提效工具,从代码片段库到各种脚手架,再到后来把ChatGPT正式塞进日常开发流。说实话,工具不在多,关键是你把它摆在哪个位置用。我见…

2026/10/18 12:16:19 阅读更多 →
中国电信计算机岗笔试:计算机网络题库精讲与高频考点解析

中国电信计算机岗笔试:计算机网络题库精讲与高频考点解析

简介:这份资料围绕中国电信计算机岗位笔试常见考点整理而成,面向正在准备电信运营商校招或社招的技术类考生,尤其适合需要系统复习计算机网络基础的人群。内容以经典笔试习题与知识点详解为主,覆盖网络分类、电路交换与分组交换对…

2026/10/18 12:16:19 阅读更多 →

最新新闻

【OpenClaw】创建一个每日热点新闻 Skill:从 SKILL.md 到定时任务与网关配置

【OpenClaw】创建一个每日热点新闻 Skill:从 SKILL.md 到定时任务与网关配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:09:48 阅读更多 →
C++内存管理:智能指针、定制Allocator与生产级观测实践

C++内存管理:智能指针、定制Allocator与生产级观测实践

简介:本资源是Roy Patrice撰写的《C Memory Management》(2025年出版)英文原版PDF电子书,面向中高级C开发者、系统程序员及参与ISO C标准实践的技术人员,聚焦内存管理这一影响程序安全性、性能与可维护性的核心能力。全…

2026/10/18 13:09:48 阅读更多 →
baltika源码拆解:从DispatcherServlet到JSP的Spring MVC完整调用链

baltika源码拆解:从DispatcherServlet到JSP的Spring MVC完整调用链

简介:javaweb框架源码-baltika是一份基于Spring Framework编写的Java Web应用开源源码项目,面向想通过读源码吃透Spring MVC请求处理流程、依赖注入、AOP与事务管理等核心机制的初中级Java开发人员,也适合准备进行框架级源码分享的进阶学习者…

2026/10/18 13:09:48 阅读更多 →
STM32温湿度采集与无线传输实战:从DHT11驱动到低功耗状态机

STM32温湿度采集与无线传输实战:从DHT11驱动到低功耗状态机

简介:这份资源是一份基于STM32的温湿度检测与无线传输毕业设计文档,面向自动化、电子信息及嵌入式方向的在校学生与初学者,帮助其理解从数据采集到无线通信的完整设计思路。文档围绕STM32单片机展开,涵盖芯片选型、CC1020无线模块…

2026/10/18 13:09:48 阅读更多 →
C# WinForms 摄像头采集:AForge.NET 拍照与避坑指南

C# WinForms 摄像头采集:AForge.NET 拍照与避坑指南

简介:本资源面向具备一定C#基础的Winform开发者与计算机视觉入门者,聚焦使用Aforge框架调用摄像头并完成拍照这一常见需求,帮助读者快速搭建可运行的摄像头采集与拍照Demo。包内为1个PDF文档,压缩包约177KB,内容以图文…

2026/10/18 13:09:48 阅读更多 →
单片机教学闭环试卷:从寄存器操作到硬件时序验证

单片机教学闭环试卷:从寄存器操作到硬件时序验证

简介:本资源是一份面向高校计算机类专业学生的《单片机原理及应用》与《微机原理及应用》课程配套考试试卷(A卷)及完整参考答案,适用于期末复习、考前自测与知识点查漏补缺。试卷涵盖MCS-51单片机结构、寻址方式、指令系统、堆栈操…

2026/10/18 13:08:47 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →