在Web交互里,按钮触发异步请求时应当展示加载状态,避免用户以为操作失效而连续提交。纯CSS方案利用border画出圆环缺口,再借助keyframes让元素持续旋转,从而形成俗称菊花图的loading效果,无需任何图片或脚本参与。

一、为什么用border加keyframes实现
传统做法常把loading做成GIF或SVG,但图片要额外请求,且改颜色得重新导出。用border构造圆环,其实是把一个正方形的四条边框分开上色:把上边框设为透明,其余三边用同色,视觉上就是一个缺月牙的圆环。配合keyframes将元素从0度转到360度,缺口随之转动,看起来就是菊花在转。
keyframes是CSS原生动画规范,主流浏览器包括IE10以上都支持。相比JS定时器改transform,它不占主线程,流畅度更好。对于按钮内的小图标,这种写法代码极少,维护成本低,也方便用CSS变量统一主题色。
二、基础旋转菊花图代码
下面给出一个最小可用的例子。我们创建一个当作loading容器,通过border与animation完成旋转。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
.spin {
width: 16px;
height: 16px;
border: 2px solid #409eff;
border-top-color: transparent;
border-radius: 50%;
animation: rotate 0.8s linear infinite;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<span class="spin"></span>
</body>
</html>
上述代码中,border-top-color设为transparent形成缺口;border-radius为50%把方块变圆;animation引用名为rotate的keyframes,0.8秒匀速无限循环。你可以直接把spin这个元素塞进按钮里,用flex布局居中即可。
如果觉得转得太快或太慢,改animation里的0.8s数值就行。想换颜色就调border里的#409eff。由于所有视觉都由CSS控制,响应式缩放只需改width和height,边框粗细同步调border宽度,不会失真。
三、在按钮中集成加载态
真实场景里,按钮点击后进入禁用并展示菊花。我们用一个普通按钮配合class切换来说明。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
.btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
background: #409eff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.btn .spin {
width: 14px;
height: 14px;
border: 2px solid #fff;
border-top-color: transparent;
border-radius: 50%;
animation: rotate 0.8s linear infinite;
}
@keyframes rotate {
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<button class="btn" id="submitBtn">
<span class="spin"></span>提交中
</button>
<script>
var btn = document.getElementById('submitBtn');
btn.disabled = true;
// 模拟请求结束
setTimeout(function(){ btn.disabled = false; btn.innerHTML = '已提交'; }, 2000);
</script>
</body>
</html>
这里按钮用inline-flex让文字和菊花横向居中,gap控制间距。点击前可通过JS把disabled设为true并显示spin元素;请求回来再恢复。注意spin的border颜色用白色以衬托蓝色背景,若按钮背景浅则要反过来。
该方案优点是无外部依赖、动画顺滑;缺点是单一缺口较细,若设计需要更粗的菊花,可调大border宽度并相应增大元素尺寸。另外在极旧浏览器上若不支持animation,可降级为静态圆点,但不影响功能。
四、常见误区与优化
有人把spin写成块级元素又忘了设宽高,结果border撑满按钮。记住spin必须是固定宽高的inline-block或flex子项,且父级用flex居中。还有人用margin左右auto去居中,在flex里多余,直接用align-items即可。
性能上,transform旋转会启用GPU合成层,比改left/top省电。若页面同时几十个菊花,建议复用同一份keyframes,不要内联多份。需要换主题时,用CSS变量如var(--load-color)替代硬编码,统一改一处就能全站生效。
五、小结
用border加keyframes做按钮loading,核心就是透明上边框加圆角加旋转动画。它轻量、易改、兼容好,适合绝大多数后台与移动端页面。掌握后,任何按钮的等待反馈都能在几分钟内补齐,不再依赖图片资源。
csskeyframesborder_loading修改时间:2026-08-02 03:39:26