button是替换元素,浏览器封装其内部盒模型,不暴露可投射inset阴影的内容表面,故box-shadow: inset无效;唯一可靠方案是用div包裹button,通过容器控制阴影、渐变和过渡实现内凹金属感。

button 元素直接加 box-shadow: inset 为什么没反应
因为 button 是替换元素,浏览器对其内部盒模型做了封装,不暴露可投射内阴影的“内容表面”。哪怕 DevTools 显示样式已生效,inset 阴影也不会渲染出来——这不是 bug,是规范行为。强行在 button 上写 box-shadow: inset 0 -2px 4px rgba(0,0,0,0.1),纯属白写。
用 div 包裹 button 实现可靠内凹金属感
这是唯一能兼顾语义、兼容性和视觉控制力的方案。关键不在“套壳”,而在把阴影控制权交给容器:
-
div容器必须设overflow: hidden,否则inset阴影可能从边缘漏出 - 容器需显式声明
width和height(或用aspect-ratio),不能靠button自撑尺寸 -
button自身要去掉干扰:border: none、background: transparent、font: inherit - 金属质感靠两层渐变叠加:基底(
linear-gradient(to bottom, #b0b0b0, #6a6a6a))+ 高光(linear-gradient(to top, rgba(255,255,255,0.3), transparent)),高光层必须写在逗号后面 - 外阴影补结构,内阴影造凹陷:
box-shadow: 0 1px 2px rgba(0,0,0,0.15), inset 0 -2px 4px rgba(255,255,255,0.3)
:active 状态下怎么模拟真实按压凹陷
只改背景色或加个 transform: translateY(1px) 不够;真正可信的按压感来自光影逻辑同步变化:
- 默认态用浅
inset阴影(如inset 0 -1px 2px rgba(255,255,255,0.4))模拟微弱反光面 -
:active态加大垂直偏移负值(如inset 0 -4px 6px rgba(0,0,0,0.2)),同时把背景色调暗 5–10% - 务必加
transition: box-shadow 0.1s ease, background-color 0.1s ease,写在默认态里,别只写 hover 或 active - 移动端需加
touch-action: manipulation,否则 iOS Safari 可能不触发:active - 避免在
:active中用filter或多层box-shadow,会卡顿或被浏览器忽略
移动端 iOS Safari 上内阴影模糊发虚怎么办
WebKit 对 inset 阴影的抗锯齿处理较弱,尤其 blur-radius > 4px 时容易灰晕、延迟渲染:
立即学习“前端免费学习笔记(深入)”;
- 把
blur-radius控制在 2–4px 范围,用偏移量变化弥补立体感 - 绝对不要和
backdrop-filter或filter: blur()同时使用,会触发额外合成层,加剧糊边 - 如果按钮有圆角,
border-radius值必须小于高度一半(比如高 48px,最大取 18px),否则内阴影在弧角处断裂 - rgba 的透明度要精细控制:高光层用
rgba(255,255,255,0.3)是安全上限,再高就泛白;暗部层用rgba(0,0,0,0.2)起步,低于 0.1 就看不出凹陷



















