应使用 @each 而非 @for 遍历颜色 map,因其天然绑定键名与值,生成语义化类名(如 .tag-success);@for 仅得数字索引,导致类名不可维护、增删颜色易错、变体扩展复杂。

直接用 @each 遍历颜色 map,比 @for 更安全、语义更清晰——它天然绑定名称与值,不会出现 .tag-1 这种无法维护的类名。
为什么不用 @for 生成多色系标签
很多人想当然地写 @for $i from 1 through length($colors),结果生成一堆 .tag-1、.tag-2。问题在于:$i 只是数字,拿不到颜色名;而标签样式必须语义化(比如 .tag-success 表示成功状态),否则开发者和协作方都看不懂。
常见错误现象:
- 生成
.tag-1 { background: #28a745; },但没人知道 1 对应什么含义 - 后续增删颜色时,数字索引全乱,
.tag-3突然从 warning 变成 info - 想加 hover 变体(如
.tag-success:hover)还得额外查 map-keys,徒增复杂度
@each $name, $color in $colors 的正确写法
颜色 map 必须是键值对结构,例如:
$colors: ( "primary": #0d6efd, "success": #198754, "warning": #ffc107, "danger": #dc3545 );
然后直接遍历:
- 类名用
.tag-#{$name},语义一目了然 - 背景色直接用
$color,无需 map-get 或 nth 查找 - 若需文字反色(如浅底深字),用
contrast-color($color)比硬编码#fff更鲁棒 - 避免在循环里嵌套
@if判断明暗——contrast-color()已内置亮度阈值逻辑
如何为每个颜色追加 light/dark 变体
别在同一个 @each 里塞 lighten() 和 darken() 调用——那会污染主色定义,且难以控制变体数量。
推荐分层处理:
- 先定义基础色 map(只含
"primary","success"等) - 再用独立
@each循环生成变体:.tag-#{$name}-light { background-color: lighten($color, 12%); } - 如果只要前两个颜色有变体,用
$keys: map-keys($colors)+@for $i from 1 through min(2, length($keys))控制范围 - 注意:Sass 3.4+ 不保证
map-keys()返回顺序,别依赖nth($keys, 1) === "primary"
命名空间冲突与作用域隔离
如果项目已存在 .tag-success(比如用了 Bootstrap),直接覆盖会导致不可预期行为。
最稳妥的做法是加前缀:
- 用字符串拼接:
.my-tag-#{$name} { background-color: $color; } - 或封装成带命名空间的 mixin:
@include tag-variant("success", $success-color); - 避免用
.tag-#{$name}-base这类冗余后缀——.my-tag-success已足够明确 - 若需 CSS 变量支持,可同时输出:
--tag-#{$name}-bg: #{$color};
真正容易被忽略的是 map key 的语义一致性:一旦设计系统把 "error" 改成 "danger",所有依赖该 key 的类名和 JS 逻辑都会断——所以改 key 名必须全局搜索,不能只动 Sass 文件。










