box-shadow: inset 必须写在 box-shadow 属性内且位置合法,正确形式为 inset 在前或在后;单层 inset 无凹陷感,需两层带方向偏移的阴影模拟明暗;:active 状态需显式 transition box-shadow;移动端 :active 不稳定,建议用 JS 切换类;深色模式下需媒体查询调整阴影对比度。

box-shadow: inset 写法必须带 inset 关键字
很多人搜“box-shadow-inset”然后直接写 box-shadow-inset: 2px 2px 4px #000,结果完全没效果——CSS 根本没有这个属性名。box-shadow 是唯一合法属性,inset 只是它的可选关键字,必须跟在 box-shadow: 后面,且位置要合法。
正确写法只有两种等效形式:
-
box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);(inset放最前) -
box-shadow: 0 2px 4px rgba(0,0,0,0.15) inset;(inset放最后)
漏掉 inset 就是外阴影;写成 box-shadow-inset 这种自造属性,浏览器直接忽略整条声明。
单层 inset 阴影不够,得用两层非零偏移模拟明暗过渡
只写 box-shadow: inset 0 0 6px rgba(0,0,0,0.2) 会得到一团均匀灰雾,毫无“凹陷”感。人眼识别内凹靠的是顶部暗、底部亮的受光逻辑,必须用两层带方向偏移的 inset 阴影协同:
立即学习“前端免费学习笔记(深入)”;
-
inset 0 2px 4px rgba(0,0,0,0.15):向下偏移,模拟按钮上沿被压后背光变暗 -
inset 0 -1px 2px rgba(255,255,255,0.6):向上偏移,在底部边缘加一条细高光,强化“压入”轮廓
注意:0 -1px 的负值不是 bug,它让高光出现在元素最底边;两层颜色透明度别超 0.6,否则盖住背景色;背景建议用浅灰(如 #f0f0f0),纯白或深色底会让内凹感消失。
:active 状态下 box-shadow 必须显式声明 transition
点了按钮但阴影没动?大概率是 transition 没覆盖 box-shadow。写 transition: all 0.2s 看似省事,但在某些浏览器里会失效,尤其当同时用了 transform 或 filter 时。
稳妥做法是只过渡真正需要的属性:
- 默认态加:
transition: box-shadow 0.15s ease, background-color 0.15s ease; - :active 里改两层
inset的偏移和模糊值,比如inset 0 3px 6px+inset 0 -2px 4px,同时背景色略变深 - 避免在 :active 中改
border-width—— 1px 的变化就会触发重排,导致动画卡顿
移动端 :active 失效不是 box-shadow 的问题
iOS Safari 和部分安卓 WebView 对 :active 支持极不稳定:轻点不触发、长按才生效、松开瞬间回退……这不是你阴影写错了,而是事件机制差异。
临时解法:
- 给按钮加
cursor: pointer和touch-action: manipulation - 更可靠的是 JS 监听
touchstart/touchend,动态切换.is-pressed类,再写对应 CSS - 千万别同时写
:active和.is-pressed,iOS 可能叠加触发两次样式变化,造成闪烁
深色模式下,原来为浅色背景设计的 rgba(0,0,0,0.15) 几乎看不见,得用 @media (prefers-color-scheme: dark) 单独调高对比度,但不能简单加透明度——否则浅色模式下就太重。



















