:active伪类必须写在默认状态之后且transition需声明在基础样式中,配合translateY位移与box-shadow外阴影协同实现真实凹陷效果,移动端需用touch-action或JS降级兜底。

:active伪类必须写在默认状态之后,否则不生效
浏览器解析CSS时按顺序匹配,:active规则如果写在按钮默认样式之前,会被后续的默认样式覆盖——尤其是当两者都设了box-shadow或transform时,按下瞬间看起来“没反应”,其实是被覆盖掉了。
正确顺序是:先定义.btn基础样式(含transition),再写.btn:active。别把:active扔到CSS文件末尾就以为万事大吉,得确认它紧接在对应选择器之后、没被其他同名规则拦截。
-
transition必须写在默认状态里,比如.btn { transition: transform 0.1s, box-shadow 0.1s; },不能只写在:active里 - 移动端 iOS Safari 默认有 300ms 延迟,需加
touch-action: manipulation才能让:active即时响应 - 某些安卓 WebView 对未绑定事件的
button或div会忽略:active,务必用语义化<button>标签
box-shadow内阴影(inset)不适合模拟按下凹陷
很多人一想到“凹陷”就本能写box-shadow: inset 0 2px 4px rgba(0,0,0,0.2),但这只是视觉错觉:它没改变元素实际位置,也没模拟受压下沉的空间压缩感,用户感知弱,且inset阴影动画性能差,低端机容易掉帧。
真正有效的凹陷,是让按钮“往下沉+阴影变厚变柔”,靠translateY()位移 + 外阴影增强来协同表达深度变化。
立即学习“前端免费学习笔记(深入)”;
- 默认
box-shadow: 0 2px 6px rgba(0,0,0,0.2),按下时改成box-shadow: 0 4px 12px rgba(0,0,0,0.3)(y偏移增大、模糊半径加大) - 同时配
transform: translateY(2px),数值要和阴影y偏移匹配——translateY(2px)配0 4px比配0 1px更可信 - 别在
:active里只改box-shadow不改transform,单侧变化会显得“悬空”或“弹起”
常见错误:阴影参数反向、过渡漏声明、outline干扰
按下效果生硬、卡顿或完全没反馈,90%出在这三处。不是代码写错了,而是细节没对齐。
- 阴影y值写小了:比如默认
0 4px,按下却写成0 1px——这像“抬起来”,不是“压下去” -
transition只写了transform,但:active里改了box-shadow,结果只有位移动,阴影瞬切 - 浏览器默认给
:active加outline(尤其Firefox),会破坏3D感,必须显式重置:.btn:active { outline: none; } - 没处理
border:默认有border: 1px solid #ccc,按下时若只动阴影和位移,边框会“浮”在新位置上,建议统一用background-clip: padding-box或干脆去边框
移动端:active失效时的替代方案
真遇到iOS或老安卓机里:active完全不触发,别硬扛,换轻量JS补位。核心是不破坏原逻辑,只做降级兜底。
- 给按钮加
data-pressable属性,用touchstart/touchend监听,动态增删is-pressed类 - 对应CSS写
.btn.is-pressed { transform: translateY(2px); box-shadow: 0 4px 12px rgba(0,0,0,0.3); } - 务必在
touchend和touchcancel里都移除类,避免状态残留 - 别用
click事件替代——它有300ms延迟,反馈滞后,用户会觉得按钮“迟钝”
translateY和box-shadow的y偏移必须同比例放大,且transition声明必须覆盖所有被变更的属性——少一个,就断一环。



















