要实现可靠的“点击凹陷”效果,必须用:active而非:hover,并确保使用<button>元素、添加touch-action:manipulation和-webkit-tap-highlight-color:transparent,配合transform+inset box-shadow及合理transition。

:hover 只能做悬停效果,真要实现“点击凹陷”,必须用 :active,且得绕过移动端不触发、样式被覆盖、过渡无效这三类常见失效点。
button:active 样式没反应?先检查是否被真正激活
iOS Safari 和部分安卓浏览器默认跳过 :active,尤其对 <div> 或 <span> 这类非原生可交互元素。不是写法错,是浏览器压根没把它当按钮处理。
- 最稳妥方案:直接用
<button>元素,别用<div class="btn"> - 若必须用非 button 元素,得同时加
role="button"和tabindex="0" - 在按钮选择器里加
touch-action: manipulation,禁用 300ms 延迟,否则:active被卡住 - 顺手加
-webkit-tap-highlight-color: transparent,避免点击先闪一层灰色高亮盖掉凹陷效果
凹陷感靠位移 + 内阴影组合,不是单改 background-color
人眼对位置和明暗梯度变化比颜色深浅敏感得多。只变 background-color 在强光屏或深色背景下几乎不可见。
- 必加
transform: translateY(1px)或transform: scale(0.98)——前者模拟下陷,后者更稳,iOS 上translateY有时触发重排闪烁 - 配
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2),inset关键字不能漏,这是内阴影的核心 - 常态按钮建议带轻微外阴影:
box-shadow: 0 2px 6px rgba(0,0,0,0.15),形成“凸起→凹陷”的对比 - 深色模式下需单独覆盖:
@media (prefers-color-scheme: dark) { .btn:active { box-shadow: inset 0 2px 4px rgba(0,0,0,0.4); } }
transition 必须写在常态里,且只过渡 transform 和 box-shadow
:active 是瞬时状态,本身不支持 transition。动画必须提前定义在常态规则中,且所有要动的属性都得有明确初始值。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
button { transform: scale(1); box-shadow: 0 2px 6px rgba(0,0,0,0.15); transition: transform 0.08s ease, box-shadow 0.08s ease; } - 别写
transition: all——颜色变化触发 repaint,低端安卓机明显卡顿 - 时间控制在
0.06s–0.1s:PC 可用0.06s,移动端建议 ≥0.08s,太短像没响应,太长反馈迟钝 - 绝对不要用
width/height/border-width动画——触发 layout thrashing,直接掉帧
顺序和覆盖问题最容易被忽略
CSS 优先级相同的情况下,后声明的规则会覆盖先声明的。:active 写在 :hover 前面,或者被通用 button 规则锁死,就等于没写。
- 把所有状态按顺序写:
button → :hover → :active → :focus - 用浏览器开发者工具的 “Styles” 面板,点击按钮后观察
:active是否打勾生效 - 避免给
:active加!important,它会破坏状态优先级逻辑 - 检查父容器有没有
pointer-events: none或overflow: hidden——后者会把inset阴影或translateY的边缘裁掉
真正难的不是写出凹陷效果,而是让 :active 在 iOS 真机、旧安卓、深色模式、禁用态切换这些边界场景下都稳定触发——每一步都要验证,不能只看 Chrome 桌面端预览。


















