box-shadow inset 不能直接实现内凹效果,因其仅添加模糊色层而非真实几何凹陷;需通过双层非零偏移阴影(上暗下亮)、浅背景、细边框及合理过渡才能模拟立体凹陷感。

box-shadow inset 为什么不能直接实现“内凹”视觉效果
box-shadow 的 inset 关键字确实会让阴影绘制在元素内部,但它本身只是“加一层暗色或亮色的模糊区域”,不是真正的几何凹陷。所谓“内凹”,其实是人眼对明暗过渡的误读——比如顶部暗、底部亮,就容易被感知为向下压进去。所以关键不是加阴影,而是控制阴影的方向、颜色和模糊度来模拟受光逻辑。
- 阴影偏移值必须非零(例如
0 2px),全零会变成均匀蒙版,失去立体感 - 暗色阴影(如
rgba(0,0,0,0.2))放在元素上边缘,配合浅色背景,才像“压下去” - 单层
inset往往不够,常需叠加两层:一层深色上边阴影模拟阴影,一层浅色下边阴影模拟反光
如何用两层 inset 阴影模拟真实内凹感
最常用且稳定的做法是上下双层 inset 阴影,分别模拟顶部遮挡和底部微反光:
box-shadow: inset 0 2px 4px rgba(0,0,0,0.15), /* 上边缘暗,制造下沉错觉 */ inset 0 -1px 2px rgba(255,255,255,0.6); /* 下边缘亮,强化凹陷轮廓 */
- 第一层负垂直偏移(
0 -1px)会让亮边出现在元素底部,但注意:它必须比第一层更模糊、更透明,否则会喧宾夺主 - 背景色要足够浅(如
#f8f8f8或白色),深色背景会让内凹感完全失效 - 边框(
border)建议设为1px solid #e0e0e0,能进一步锚定边缘,避免阴影“漂浮”
常见翻车现场:inset 阴影不显示或发虚
这不是代码写错了,而是被几个隐藏条件卡住:
- 元素没有明确的
background-color(哪怕设成transparent),inset阴影在某些浏览器里会不可见 - 父容器设置了
overflow: hidden,而阴影区域刚好被裁掉(inset阴影仍受父级裁剪影响) - 使用了
border-radius但没同步调整box-shadow的圆角适配,导致阴影边缘生硬断裂 - 在 Retina 屏上,
1px偏移可能被缩放模糊,可改用0.5px或启用transform: scale(1)强制设备像素对齐
要不要用 box-shadow inset 做按钮按压反馈
可以,但要注意交互节奏。纯 CSS 按压效果容易显得“假”,因为缺少位移和形变。如果只靠 inset 阴影切换,建议:
立即学习“前端免费学习笔记(深入)”;
- 默认状态用轻量双层阴影(如上例)
-
:active状态增加阴影深度:inset 0 4px 6px rgba(0,0,0,0.25),同时微调背景色变深 5% - 必须搭配
transition: box-shadow 0.1s, background-color 0.1s,否则切换生硬 - 别忘了禁用默认焦点轮廓(
outline: none),否则和阴影打架
真正难的是让“凹下去”的感觉和用户点击时机严丝合缝——稍慢就滞后,稍快又像抽搐。多数情况下,加一点点 transform: translateY(1px) 比只调阴影更可信。


















