用 shadow-depth() 自定义函数封装 box-shadow,通过预设深度映射表返回带单位的合法 list 值,配合 #{...} 插值或 @mixin 调用,支持深色模式动态配色与 z-index 协同约定。

如何用 Sass 函数封装 box-shadow 并动态控制深度
直接说结论:用 shadow-depth() 自定义函数 + 预设深度映射表,比硬写多层 box-shadow 值更可控、可维护。别用 mixins 简单包裹——它没法做数值运算和条件映射,容易在换主题或适配深色模式时崩。
shadow-depth() 函数怎么写才不踩坑
核心是把“深度”这个语义概念,映射成真实可用的 box-shadow 值(h-offset v-offset blur spread color),而不是拼字符串。常见错误是返回带单位的字符串,导致无法参与计算或被 CSS 预处理器忽略。
- 必须返回一个合法的
box-shadow值列表(Sass list),不是字符串 - 用
map-get($shadows, $depth)查表,别用@if $depth == 'sm'这类硬判断——加新层级时要改一堆@if - 预设表里所有值都带单位(如
0px 2px 4px 0px),避免运行时单位混用报错
@function shadow-depth($depth: 'md') {
$shadows: (
'xs': (0px 1px 2px 0px rgba(0, 0, 0, 0.05)),
'sm': (0px 1px 3px 0px rgba(0, 0, 0, 0.1)),
'md': (0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -1px rgba(0, 0, 0, 0.06)),
'lg': (0px 10px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px -2px rgba(0, 0, 0, 0.05))
);
@return map-get($shadows, $depth);
}
为什么不能直接在 box-shadow 属性里调用函数
因为 box-shadow 是 CSS 属性,而 Sass 函数返回的是 Sass list,浏览器不认识。必须用 @include 或属性内联展开。常见错误现象:box-shadow: shadow-depth('lg'); 编译后变成空白或报错 Invalid CSS after "...-shadow:": expected expression。
- 正确写法是:用
#{...}插值展开,或封装成@mixin再调用 - 插值写法简洁但不可复用:
box-shadow: #{shadow-depth('lg')}; - 推荐封装为
@mixin shadow($depth),内部用@apply或直接展开,便于后续加逻辑(比如根据$color-mode自动切色) - 注意:多层阴影返回的是 list,插值后会自动空格连接,无需手动
join()
深色模式下阴影变灰还是变透?关键看颜色生成逻辑
很多人以为换个 rgba(255, 255, 255, 0.08) 就完事,结果在深底色上阴影“消失”。真正要动的是 alpha 值和 base color 的组合策略,不是简单替换。
立即学习“前端免费学习笔记(深入)”;
- 别用固定
rgba(0,0,0,...)或rgba(255,255,255,...)——它们在不同背景对比度下表现不稳定 - 推荐用
hsl()+ 变量控制明度:比如hsl(0, 0%, if($dark-mode, 20%, 0%), $alpha),让灰阶随主题滑动 - 更稳妥的做法是把阴影颜色抽成变量
$shadow-color-base,在 dark mode 文件中重定义,函数本身不动 - 性能影响很小,但若在大量组件中高频调用,建议提前编译好各深度值,避免运行时查表开销
shadow-depth('lg') 往往意味着该元素应处于较高堆叠上下文,但函数本身不处理 z-index。得靠设计系统约定或额外 mixin 配合,否则视觉“浮起感”会失真。


















