直接用box-shadow配合反向内阴影可实现真实轻量凹陷效果,无需伪元素或js;关键在于用两层方向相反的inset阴影(如inset 0 2px和inset 0 -2px)模拟顶部微暗、底部微亮的受光逻辑,并在:active态增强偏移与透明度,辅以transform: translatey(1px)强化按压错觉。

直接用 box-shadow 配合反向内阴影就能做出真实、轻量、无伪元素依赖的凹陷效果,不需要 ::before 或 JavaScript。
为什么不用伪元素做凹陷文字或按钮
很多教程推荐用 ::before + transform: translateZ(-1px) 模拟凹陷,但实际项目中容易出问题:
-
::before必须设content: "",否则不渲染,且默认是 inline 元素,需额外加display: block - 当按钮有
border-radius时,::before的阴影边缘常出现锯齿或裁剪,尤其在 Safari 中 - 如果按钮用了
background: linear-gradient(),伪元素会遮盖渐变层,导致颜色断层 - 移动端 touch 事件区域可能因伪元素层叠错位,触发不灵敏
box-shadow 实现按钮凹陷的关键参数
核心是使用「多层内阴影」叠加:一层深色压暗顶部,一层浅色提亮底部,模拟光线入射角度。例如:
button {
background-color: #f0f0f0;
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.15), /* 底部微亮 */
inset 0 -2px 4px rgba(255, 255, 255, 0.3); /* 顶部微暗 */
}
注意三点:
-
inset必须写在最前面,否则会被当成外阴影忽略 - 两个阴影的
y偏移方向要相反(一个+2px,一个-2px),否则只有一侧有层次感 -
rgba()的 alpha 值不宜超过0.3,否则在深色背景上会发灰、失真
点击态(:active)如何强化凹陷感
用户按下按钮时,应让凹陷“加深”,而不是简单变色。错误做法是只改 background-color,这会破坏立体一致性。
正确做法是增强内阴影深度与对比度:
button:active {
box-shadow:
inset 0 4px 8px rgba(0, 0, 0, 0.25),
inset 0 -4px 8px rgba(255, 255, 255, 0.4);
transform: translateY(1px); /* 微下沉,配合阴影更自然 */
}
这里 transform: translateY(1px) 不是为了位移本身,而是抵消按下时视觉重心上浮的错觉——人眼会把阴影变重 + 位置微调同时解读为“被按进去了”。
真正难的是阴影参数和背景色的耦合:同一组 box-shadow 值在浅灰背景上成立,在深蓝背景上可能完全看不见。每次换主色,都得重新调两层 rgba() 的明度与透明度,不是套个 class 就完事的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











