:active伪类是实现按钮按压效果最直接的方式,它在元素被激活(如鼠标按下、触屏点击)时生效,松开即失效;需写在:hover之后、配合transform:scale()和基础态transition实现轻量回弹动画,移动端需确保可聚焦并处理touch事件。

用 :active 伪类触发按压状态样式
按钮按压效果最直接的实现方式就是监听用户按下鼠标(或触摸)的瞬间,:active 正是为此设计的伪类——它在元素被激活(如鼠标左键按下、空格键触发、触屏点击中)时生效,松开即失效。
注意::active 不代表“已点击完成”,而是“正在被按下”的瞬态,所以它天然适合模拟按压反馈。但它的持续时间极短(毫秒级),若想延长视觉反馈,不能靠它本身,而要配合 JavaScript 或切换 class。
-
:active必须写在:hover之后才有效(CSS 优先级规则),否则会被覆盖 - 移动端需确保元素可聚焦(如
button默认可,div需加tabindex="0")才能触发:active - 在 iOS Safari 中,
:active默认不生效,需给<body>加cursor: pointer或绑定空onclick(现代方案推荐用touch-action: manipulation)
配合 transform: scale() 做视觉收缩
纯颜色变化太单调,真实按压感来自形变。用 transform: scale(0.95) 让按钮轻微内缩,松开后自动回弹,比改宽高更轻量且不触发重排。
关键点在于过渡必须作用于正常态,而不是 :active 态本身:浏览器只对「离开 :active」做过渡,所以要把 transition 写在基础选择器上。
立即学习“前端免费学习笔记(深入)”;
button {
transition: transform 0.1s ease;
}
button:active {
transform: scale(0.95);
}
- 避免写
transition: all 0.1s—— 容易因其他属性变化(如 color)导致意外动画 - 慎用
scale(0.9)以下值,过强收缩会破坏布局对齐(尤其 inline 元素) - 如果按钮有边框,
scale可能导致边框模糊,可加will-change: transform或用translateZ(0)触发硬件加速
需要保持按压态?别依赖 :active,改用 class 控制
当按钮要实现“按下后保持凹陷”(比如开关、工具栏选中态),:active 就不够用了——它只响应瞬时操作,无法记忆状态。
此时必须交由 JavaScript 切换 class,并用 CSS 定义该 class 的样式,例如:
button.pressed {
transform: scale(0.95) translateY(1px);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
}
- 不要用
:focus代替——键盘聚焦和鼠标按压语义不同,且容易被 Tab 键干扰 - 如果支持键盘操作,记得同时监听
keydown.enter和keydown.space并阻止默认行为 - 移动端要考虑 touchstart/touchend,而非只监听 click(click 有 300ms 延迟)
兼容性与性能陷阱
:active 在所有现代浏览器中都支持,但行为细节有差异:Firefox 在拖拽出元素区域后仍保持 :active,Chrome 则立即解除;Safari 对非可点击元素的 :active 支持更严格。
- 避免在
:active中修改display、width、height等触发布局的属性——会导致卡顿甚至闪烁 - 不要给大量按钮同时加复杂
:active动画,低端设备可能出现掉帧 - 如果按钮背景是渐变或阴影,按压时建议只动
transform和box-shadow深度,别改渐变色 stops——重绘成本高
真正难的不是写出按压效果,而是让这个效果在各种输入方式(鼠标、触控、键盘)、各种设备、各种交互路径下都表现一致且不抢戏。多数 bug 出在假设用户只用鼠标点击。


















