纯CSS可实现丝滑轻量转圈加载动画:用border+border-radius+transform:rotate()组合,设单边实色其余半透明形成缺口,配合@keyframes匀速旋转;需注意兼容性、GPU加速及display/visibility切换差异。
纯 CSS 就能做出丝滑、轻量、可定制的转圈加载动画,不需要 JS 控制启停,也不依赖第三方库。关键在边框 + 旋转 + 半透明缺口的组合,浏览器原生支持,手机端也稳。
border + border-radius + animation 做最简 spinner这是最常用也最可靠的方案:画一个正方形 div,加等宽边框,把其中一边设为实色,其余三边半透明,再用 @keyframes 驱动 transform: rotate()。
border-radius: 50% 是必须的,否则圆不起来border-top-color(或 border-right-color)要单独设,形成视觉“缺口”,这是旋转感的来源animation: spin 1s linear infinite 中的 1s 可调快慢;linear 保证匀速,避免卡顿感display: inline-block 或 block,否则 width/height 在某些场景下可能不生效示例代码:
.loader { width: 32px; height: 32px; border: 3px solid rgba(0,0,0,0.1); border-top-color: #3498db; border-radius: 50%; animation: spin 1s linear infinite;}@keyframes spin { to { transform: rotate(360deg); }}
transform: rotate() 比 animation: rotation 更靠谱CSS 没有 rotation 这个 animation 属性,常见错误是搜到过时教程写 animation: rotation 1s infinite —— 浏览器直接忽略,动画不跑。
立即学习“前端免费学习笔记(深入)”;
transform: rotate() 配合 @keyframes,这是唯一标准写法-webkit-transform 兼容旧版 Safari,但现代 iOS 已基本不需要will-change: transform 或 transform: translateZ(0) 强制 GPU 加速,尤其在低端安卓机上明显rotate() 同时操作 left/top 等布局属性,会触发重排,掉帧display: none 和 visibility: hidden 怎么选两者行为差异很大,选错会导致动画重置或布局跳动。
display: none 会彻底移出渲染流,下次显示时动画从头开始播 —— 适合“请求开始→显示→请求结束→隐藏”这种明确生命周期visibility: hidden 保留占位,动画暂停但状态保留,显示时继续播 —— 适合需要保持动画连续性的场景(比如长轮询中反复闪现)opacity: 0 + pointer-events: none,视觉隐藏且不打断动画,还能避免焦点丢失问题style.display,用 class 切换更可控:element.classList.toggle('is-loading')
看似自由调整,实际几个参数互相牵制:
border-width 和 width/height 要匹配:比如 width: 40px + border: 4px,实际内容区只剩 32×32,太小会糊hsl() 或 rgba(),方便后期一键换主题色或调节透明度animation-duration 小于 0.6s 容易眼花,大于 1.5s 会让用户觉得“卡住了”,0.8–1.2s 是舒适区间border-top-color,记得同步调 border-color 的 alpha 值,否则底边框会透出难看灰边真正难的不是写出来,而是让 spinner 在各种屏幕密度、缩放比例、暗黑模式下都保持清晰不糊、不偏心、不闪烁 —— 这些细节得一个个在真机上点开开发者工具调。