scss 的 @function 不支持递归调用,因编译器静态解析时禁止函数内嵌套自身调用;应使用 @mixin 配合 @for 循环或 @each 遍历 map 生成缩进类,确保静态、可控且兼容。

SCSS 里不能定义递归函数
SCSS 的 @function 不支持递归调用——编译器会在解析阶段报错 "Function calls may not be nested inside their own definition"。这不是语法写错了,而是语言设计限制:Sass 在编译时做静态展开,无法处理运行时才确定深度的调用链。
所以,试图写类似这样的代码会直接失败:
@function indent($level) {
@if $level == 0 { @return 0; }
@else { @return 1rem + indent($level - 1); } // ❌ 编译报错
}
用 @mixin + @for 替代递归生成缩进类
实际项目中要生成 .indent-1、.indent-2….indent-10 这类样式,应该用 @mixin 配合 @for 循环,这是稳定、可预测且被广泛采用的方式。
-
@for是编译期展开,不依赖函数调用栈,完全规避递归限制 - 缩进值可用乘法计算(如
$level * 1.5rem),也可查表(用map-get查预设层级值) - 生成的 CSS 类名和声明都是静态的,无运行时开销,兼容所有 Sass 版本(包括 Dart Sass 1.7+)
示例:
@mixin generate-indent-classes($max: 10, $unit: 1.5rem) {
@for $i from 1 through $max {
.indent-#{$i} {
padding-left: $i * $unit;
}
}
}
<p>@include generate-indent-classes(5); // 生成 .indent-1 到 .indent-5</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板"><img
src="https://img.php.cn/upload/webcode/000/000/018/178607072210981.jpg" alt="CSS婚礼策划服务机构宣传网站模板" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="overflowclass">CSS婚礼策划服务机构宣传网站模板</a>
<p class="overflowclass">CSS婚礼策划服务机构宣传网站模板是一款适合提供婚礼策划和婚庆服务机构宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。</p>
</div>
<a rel="nofollow" href="/xiazai/code/12093" title="CSS婚礼策划服务机构宣传网站模板" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
需要动态计算缩进值?用 map + @each 更安全
如果各层级缩进不是等差(比如 1rem、2.25rem、4rem),硬写 @for 乘法就不够用了。这时用 map 存映射关系,再用 @each 遍历更清晰,也避免魔数和算术错误。
- 键名建议用数字字符串(如
"1"),避免 map key 类型混淆 - 值必须是合法 CSS 尺寸(带单位),不能是纯数字
- 注意
map-keys()返回顺序不保证,若需严格序号顺序,仍应优先用@for
示例:
$indent-steps: (
"1": 1rem,
"2": 2.25rem,
"3": 4rem,
"4": 6.5rem
);
<p>@each $key, $value in $indent-steps {
.indent-#{$key} {
padding-left: $value;
}
}</p>
别在 :deep() 或嵌套选择器里硬套“递归”逻辑
有人尝试用 & > & 或 :deep(&) 模拟嵌套缩进,这看似“自动延伸”,但实际问题很多:
- 生成的选择器权重爆炸(
.a > .a > .a > .a),难以覆盖 - 无法控制最大深度,CSS 文件体积不可控
- 和 BEM 或 utility-first 策略冲突,后期维护成本高
- Vue 的
:deep()是作用域限定机制,不是样式生成工具
真要响应 DOM 嵌套深度,应由 JS 控制 class 名(如根据 node.depth 动态绑定 indent-3),CSS 层只提供固定类集合。
真正卡住的地方往往不是“怎么写递归”,而是没意识到 Sass 的函数本质是编译期求值工具——它没有栈,也不执行,只是文本生成器。把需求拉回循环和映射,事情就简单了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










