@function生成多层box-shadow最稳,IE10+兼容;@mixin无法循环拼接合法值,易出错且难维护;函数须返回逗号分隔阴影列表,参数需符合物理逻辑,并注意overflow和border-radius适配。

直接用 @function 生成多层 box-shadow 是最稳的方案,不依赖运行时 JS,编译后仍为单条 CSS 声明,IE10+ 全兼容。
为什么不能靠 @mixin + 多个 box-shadow 参数硬写
手动拼接多层阴影容易出错,比如漏掉逗号、混用单位、透明度没衰减——结果就是“影子糊成一块”或“只有最上层生效”。@mixin 本身不支持循环生成值列表,你得自己写死每一层,维护成本高,且无法动态控制层数。
- 浏览器对单条
box-shadow中的多层阴影支持良好,但对多个独立box-shadow声明(如重复写两次box-shadow:)会覆盖前一条,只留最后那个 -
@mixin shadow-depth($layers)内部若用@for拼字符串,最终输出的是带引号的字符串字面量,不是合法的 CSS 值,编译报错 - 真正能返回可赋值给
box-shadow的,只有@function返回的未加引号的值列表(comma-separated list)
@function depth-shadow($layers) 必须这样写
函数必须返回一个用 comma 连接的阴影值列表,不能是字符串,也不能是空格分隔。每层参数要体现物理逻辑:距离递增、模糊递增、透明度递减。
-
$distance用$i * 2px线性增长,模拟光源固定时远层阴影下移更明显 -
$blur用$i * 4px,比距离增长更快,符合真实散射规律 -
$alpha用0.08 - ($i * 0.02)保证从 0.06 → 0.04 → 0.02 → 0,避免底层全黑或不可见 - 颜色必须用
rgba(0, 0, 0, $alpha)或更好是rgba(var(--shadow-r, 0), var(--shadow-g, 0), var(--shadow-b, 0), $alpha),方便深色模式切换
@function depth-shadow($layers: 3) {
$shadows: ();
@for $i from 1 through $layers {
$distance: $i * 2px;
$blur: $i * 4px;
$alpha: 0.08 - ($i * 0.02);
$shadow: 0 $distance $blur rgba(0, 0, 0, $alpha);
$shadows: append($shadows, $shadow, comma);
}
@return $shadows;
}
调用时别漏掉括号,也别套错作用域
depth-shadow(4) 返回的是值列表,必须直接赋给 box-shadow,不能包在引号里,也不能放在 @if 或 @each 里当普通变量用。
- ✅ 正确:
box-shadow: depth-shadow(4); - ❌ 错误:
box-shadow: "#{depth-shadow(4)}";(变成字符串,无效) - ❌ 错误:
@if depth-shadow(4) { ... }(函数返回值不能当布尔判断) - ⚠️ 注意:如果项目用了 CSS 变量控制主题色,
rgba()里别硬写#000,改用rgba(var(--shadow-color, 0 0 0), $alpha),并在:root中定义--shadow-color: 0 0 0;
两个真实场景中必踩的坑
即使函数写对了,这两点也会让立体感完全失效:
- 父容器设了
overflow: hidden—— 多层阴影本质是向外绘制,超出元素边界会被裁掉,看起来像只有一层浅影 - 元素本身有
border-radius但值太小(比如2px),而阴影模糊半径达16px,导致边缘过渡生硬,“浮起感”断裂;建议border-radius至少设为最大$blur值的 1/3(例如用depth-shadow(4)就配border-radius: 6px)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











