必须用 Map 而非 List 或独立变量,因 Map 唯一支持语义化键值映射(如 "sm": 576px),保障可读性、可遍历性与集中维护;键名须加引号防解析错误,@each 遍历最可靠,嵌套方向类需动态拼属性名并校验 key 存在。

直接用 @each 遍历 Map 是唯一靠谱方式,其他写法(比如拼字符串、用 @for、手动列类名)都会在维护性或语义性上崩掉。
为什么必须用 Map 而不是 List 或独立变量
Map 是 Sass 中唯一能同时携带「可读键名」和「对应值」的数据结构。工具类本质是「名字 → 样式规则」的映射,比如 "sm" → 576px、"primary" → #007bff。List 只有顺序没有语义,独立变量无法遍历也无法统一管理。
- 写成
$spacers: (0.25rem, 0.5rem, 1rem)——@each只能拿到值,没法生成.m-1这种带语义的类名 - 写成
$sm: 576px; $md: 768px;—— 每次增删都要改多处,JS 同步时极易脱节 - 正确姿势:
$breakpoints: ("sm": 576px, "md": 768px),后续所有逻辑只认这一个源头
Map 键名和引号的坑必须踩准
键名是否加引号,直接影响编译行为和错误定位。Sass 对字符串键和未加引号键的解析完全不同。
- 字符串键(推荐):
"sm"、"lg"—— 安全,@each $key, $val in $map中$key就是字符串,插值.d-#{$key}-none输出.d-sm-none - 未加引号键:
sm(无引号)—— Sass 会先尝试找变量$sm,找不到就报错Undefined variable "sm" - 数字键可不加引号:
1: 0.25rem合法,但混用("1": ..., 2: ...)易引发混乱,建议统一加引号 - 键名别用连字符:
"x-large"会导致插值后类名变成.d-x-large-none,CSS 解析为d-x和large-none两段,出错
@each 嵌套生成方向类时属性名不能硬拼
生成 .mt-2、.pl-4 这类带方向的工具类,靠一层 @each 不够,必须嵌套,且 CSS 属性名要动态拼对。
立即学习“前端免费学习笔记(深入)”;
- 方向映射得明确:比如
$dirs: ("t": "top", "r": "right"),不能简写成("t": "t"),否则margin-#{$dir}会产出非法属性margin-t - 属性名拼接必须带连字符:
margin-#{$full}✅,margin#{$full}❌(输出margintop) - 复合方向(如
x表示左右)需用@if分支处理:@if $full == "left right",然后分别写margin-left和margin-right - 漏写
$value在@each $key, $value in $map中会导致$key实际是整个键值对,编译报错Invalid null operation
map-get() 取不到值时不会报错,但样式会静默消失
map-get($map, "lg") 查不到键时返回 null,而 null 插入媒体查询或属性值中,会编译成空字符串,浏览器直接忽略整条规则,且无任何警告。
- 例如:
@media (min-width: map-get($breakpoints, "lgd"))→ 编译为@media (min-width: )→ 整条规则失效 - 解决办法:封装安全函数,比如
@function breakpoint($key) { @if not map-has-key($breakpoints, $key) { @error "Unknown breakpoint: #{$key}"; } @return map-get($breakpoints, $key); } - 调用时务必带引号:
breakpoint("lg"),写成breakpoint(lg)会被当变量,报错Undefined variable "lg" - 调试时加
@debug map-keys($breakpoints)看当前有哪些合法键,比猜快得多
最常被忽略的是 Map 的嵌套层级和 key 匹配精度:map-get($props, 'padding') 查不到,往往不是值不存在,而是原始 Map 里 key 是 padding(无引号)、Padding(大小写错)或 "padding-value"(拼写多字),而不是你认为的那个字符串。


















