必须将transition写在按钮默认状态而非:hover或:active中,否则移出或释放时无过渡;应指定background-color、transform等可动画属性,避免all、display、padding等触发重排。

按钮本身没有微交互,是你加的 CSS 和 JS 让它“活起来”的。不写:hover、:active、transition,它就只是个静态方块。
为什么:hover动画卡顿或没反应
常见错误是只写transition: background-color 0.3s,结果鼠标移上去像延迟半秒才变色;或者用了transition: all 0.3s,导致改padding或height时触发重排、视觉抖动。
- 必须在默认状态(非伪类)里声明
transition,且只列明确可动画的属性:background-color、transform、box-shadow - 多属性联动更顺滑:比如同时过渡
background-color和transform: scale(1.02),别只动颜色 - 避免在
:hover里改padding、margin、width等会触发布局计算的属性 - 移动端无
hover,纯靠触摸反馈时,这个样式根本不会生效——得补:active和touch-action: manipulation
:active状态为什么点下去没反馈
最常被忽略的是:浏览器只对原生button元素应用:active,而你用div或a模拟按钮,又没设cursor: pointer,iOS Safari 就直接跳过这个状态。
- 确保元素是
<button type="button">,不是<div onclick>或<a href="#"> - 给元素加
cursor: pointer和touch-action: manipulation,否则 iOS 会禁用:active -
:active里别只改颜色——色盲用户看不到;建议配transform: scale(0.98)或opacity: 0.85 - 如果用了 Shadow DOM 或 CSS-in-JS,检查
:active样式是否被作用域隔离了
加载中状态该不该直接改innerText
直接把“提交”替换成“提交中…”会导致按钮宽度突变、文字居中偏移,还可能被屏幕阅读器误读为内容变更,而不是操作阻塞。
立即学习“前端免费学习笔记(深入)”;
- 用伪元素控制加载文案:
::after+content+visibility: hidden占位 - 配合
aria-busy="true"和disabled属性,让辅助技术知道当前不可操作 - 别删原文字,用
clip-path或visibility: hidden隐藏,保留布局空间 - JS 控制时,优先用
classList.add("is-loading")切换状态,而不是硬写element.style.opacity = 0.6
transition和@keyframes怎么选
简单状态切换(悬停、按下、禁用)全用transition;需要多帧、循环、路径运动(比如摇晃、旋转加载)才上@keyframes。
-
transition必须写在默认状态,且不能含display、height这类不可动画属性 -
@keyframes动画要用animation-fill-mode: forwards保持终态,否则鼠标移开就跳回原样 - JS 触发动画只能加 class,比如
btn.classList.add("is-shaking"),别直接写btn.style.animation = "shake 0.5s" - 动画结束后监听
animationend事件清理 class,否则重复点击可能叠加动画
真正难的不是写多少动画,而是状态边界是否连贯:从:hover进:active有没有过渡衔接,加载结束时焦点是否回到按钮,键盘 Tab 是否仍能进入——这些细节漏掉,用户就觉得“按钮反应慢”。



















