纯CSS三点循环加载动画需用@keyframes显式定义content各帧值并配合steps(3)实现精准切换,避免使用linear等无效缓动。

用 ::after 伪元素配合 content 实现三点循环显示
纯 CSS 实现“加载中…”的点数变化(· → .. → ... → ·),关键不是靠 JS 改 content,而是用 CSS 动画控制多个状态的 content 值切换。浏览器不支持在 @keyframes 中直接动画化 content,所以得用「状态帧 + 精确时长」模拟。
常见错误是写成 content: "·"; animation: dots 1s infinite; 却没定义关键帧里的不同 content 值,结果动画无效——content 不是可动画属性,只能靠离散帧硬切。
- 必须用
@keyframes显式声明每个阶段的content值,例如0% { content: "·"; }、33% { content: ".."; } - 动画总时长建议设为 3 的倍数(如
1.2s),让每点停留时间一致:1.2s ÷ 3 = 0.4s/点 -
::after必须设置content: ""初始值,否则伪元素不渲染;且需display: inline-block或类似值才能生效
完整可运行的 CSS 片段(含必要样式补全)
只写动画逻辑不够,漏掉这些会导致点不显示、位置错乱或字体异常:
-
content值必须用英文句点.,中文顿号或全角符号会撑宽、换行 - 要加
white-space: pre;防止多个点被合并或折行 - 若父容器是
flex或inline元素,::after默认是inline,可能上下对不齐,加vertical-align: middle;更稳 - 字体大小建议显式设为
font-size: inherit;,避免继承缩放失真
.loading::after {
content: "";
display: inline-block;
vertical-align: middle;
font-size: inherit;
white-space: pre;
animation: loading-dots 1.2s steps(3) infinite;
}
@keyframes loading-dots {
0% { content: "·"; }
33% { content: ".."; }
66% { content: "..."; }
100% { content: "·"; }
}
为什么 steps(3) 比 linear 更可靠
用 linear 会让 content 在帧之间插值——但 content 无法插值,浏览器实际表现是跳变+卡顿,尤其在低帧率设备上容易漏帧。而 steps(3, end)(steps(3) 是简写)强制把动画切成 3 步,每步停满时长,确保每个点稳稳显示 0.4 秒。
立即学习“前端免费学习笔记(深入)”;
-
steps(3)表示:动画全程分 3 步,每步结束时才切换内容(end是默认行为) - 若用
steps(3, start),会在 0% 瞬间切到第二帧,首帧“·”几乎看不见 - 别用
ease或cubic-bezier:它们对content无意义,还可能干扰 step 切换节奏
IE 和旧版 Safari 的兼容性现实
content 在 @keyframes 中的支持,Chrome 55+、Firefox 55+、Edge 79+ 没问题,但 IE 完全不支持,Safari ≤ 13.1 会忽略整个 @keyframes 块——导致伪元素彻底不显示内容。
- 降级方案:用三个真实
<span></span>元素 +opacity动画,或改用背景图 SVG 动画 - 如果必须支持 Safari 12,可改用单个点 +
box-shadow投影生成多点,再动画opacity或transform - 检测方式:在开发工具里删掉
@keyframes后看是否回退到空内容,就能快速验证是否生效
真正麻烦的不是写法,而是当设计师说“三点要呼吸感”,你得意识到:CSS 里没有“呼吸”,只有帧与帧之间那 0.4 秒的留白和精准的 step 切换节奏。


















