真实按压感的3D按钮需双层box-shadow(高光在前、投影在后)、:active时transform: translateY(2px)下沉、box-shadow收缩、border-bottom变细,并在默认态设transition,顺序与位移方向错误会导致立体感失效。

直接用 box-shadow 双层叠加 + transform: translateY() + 合理过渡,就能做出真实按压感的 3D 按钮,不需要 JS、图片或复杂库。
box-shadow 必须写两层,顺序不能错
单层 box-shadow 只会让按钮“浮在页面上”,不是“凸起”。真正模拟光源照射,得一高光一投影,且高光必须写在前面:
-
box-shadow: 0 -2px 0 2px #fff, 0 3px 6px rgba(0,0,0,0.15)—— 第一段是顶部亮边(负 vertical offset),第二段是底部暗影 - 顺序反了(比如暗影写前)会被盖住,高光消失,立体感直接垮掉
- 深色背景上别用纯白高光,改用
#f0f0f0或hsl(0,0%,95%),避免割裂 - 移动端
blur值别超6px,否则阴影边界模糊,手指点不准
:active 状态必须同步位移和阴影收缩
只改背景色或加 opacity,用户根本感觉不到“被按下去”。真实反馈是下沉 + 受压变形:
-
transform: translateY(2px)—— 注意是向下位移,不是向上 -
box-shadow: 0 1px 3px rgba(0,0,0,0.2)—— y 偏移和 blur 都比默认态小,模拟受压后阴影收窄 -
border-bottom: 2px solid #ccc在默认态,:active 时缩到1px,强化“被压扁”感 -
transition: transform 0.18s, box-shadow 0.18s, border-bottom 0.18s—— 别写all,否则拖慢无关属性
transition 必须写在默认状态,不是 :active
如果把 transition 放在 :active 里,按下瞬间没有缓动,像卡顿或失效。正确写法:
立即学习“前端免费学习笔记(深入)”;
- 在按钮默认样式里写:
transition: transform 0.18s, box-shadow 0.18s - 移动端加
-webkit-tap-highlight-color: transparent,否则点击闪白 - 别忽略重置
outline和border:outline: none; border: none或设为透明边框,否则某些浏览器会加默认轮廓,破坏 3D 感 - 文字用
text-shadow: 0 1px 0 #fff(浅底)或0 -1px 0 #000(深底),让字“浮”在表面
悬停时想让阴影“锚定不动”,就得反向补偿偏移
常见错误:只写 transform: translate(-5px, -5px),结果整个按钮连同阴影一起飘走。理想效果是按钮上提,阴影位置不变:
- 按钮
:hover位移translate(-5px, -5px) - 同时把
box-shadow的v-shadow和h-shadow各加5px,比如从6px 6px→11px 11px -
transition必须包含box-shadow,推荐写all 0.3s ease,否则阴影跳变 - 这个技巧对图片按钮也适用,但图片要先设
display: inline-block才能响应:hover
最容易被忽略的是阴影书写顺序和 :active 的位移方向——写反了,按钮就不是“按下去”,而是“跳起来”。



















