sass 的 @if 是编译期指令,必须包裹完整 css 规则而非仅声明块,且只能用于顶层或 @mixin 内;变量需提前定义并推荐用 !default;响应式断点须用函数封装,深色模式应通过构建变量或运行时媒体查询实现。

@if 必须包裹完整规则,不能只包声明块
Sass 的 @if 是编译期指令,它不生成“条件选择器”,而是决定“要不要输出这一整条 CSS 规则”。常见错误是写成:.btn { @if $theme == "dark" { color: #fff; } }——这会报 SyntaxError: Invalid CSS after ""。因为 @if 不能嵌套在选择器内部,只能作用于顶层规则或 @mixin 体内。
正确做法是把整个规则(选择器 + 声明)都包进去:
.btn {
padding: 8px 16px;
}
@if $theme == "dark" {
.btn {
background-color: #222;
color: #eee;
}
} @else {
.btn {
background-color: #f5f5f5;
color: #333;
}
}
- 变量
$theme必须提前定义,且用!default声明更安全(避免未定义报错) - 每个分支都必须含完整选择器,否则编译后可能丢失样式
- 编译结果里只会保留命中分支的 CSS,不会残留
@else分支的代码
@mixin + 参数更适合复用型条件逻辑
当同一套条件判断要用于多个组件(比如按钮、卡片、表单控件),硬写多组 @if 会重复。这时应封装为带参数的 @mixin:
@mixin theme-variant($bg, $text) {
background-color: $bg;
color: $text;
border: 1px solid if(lightness($bg) > 70%, #ccc, #444);
}
.btn-primary {
@include theme-variant(#007bff, #fff);
}
-
if()函数可用于属性值插值(如上面的border),但它只是返回一个值,不能控制规则是否生成 -
@mixin内部仍可嵌@if,比如根据$size参数切换padding和font-size - 注意:传入的变量类型要一致,
if($cond, $a, $b)中$a和$b单位需兼容(如不能一个是px,一个是rem)
响应式断点要用函数封装,别在 @if 里硬写媒体查询
想按屏幕尺寸切样式?别这么干:@if $breakpoint == "md" { @media (min-width: 768px) { ... } }——$breakpoint 是字符串变量,@media 查询本身不接受变量,Sass 编译器无法把字符串转成有效查询。
正确方式是用函数返回断点值,再放进 @media:
$breakpoints: (sm: 576px, md: 768px, lg: 992px);
@function breakpoint($name) {
@return map-get($breakpoints, $name);
}
@media (min-width: breakpoint(md)) {
.container {
max-width: 720px;
}
}
-
breakpoint()必须在编译期求值,所以它只能读取静态 map,不能读取 JS 或 CSS 变量 - 如果
map-get找不到 key,返回null,会导致@media (min-width: null),浏览器忽略该规则但不报错——容易误以为生效了 - 单位统一用
px最稳妥;若需em或rem,函数内做转换,别让调用方自己算
深色模式适配不能依赖 @if 读取 prefers-color-scheme
@if 完全看不到 @media (prefers-color-scheme: dark) 这类运行时环境,它只认 Sass 变量。所以不能写:@if prefers-color-scheme == "dark" { ... }——语法错误,且语义错位。
真实项目中两种主流做法:
- 用 Sass 变量模拟主题(如
$theme: "dark"),配合构建脚本生成两套 CSS 文件,分别加载 - 放弃编译期判断,直接写 CSS 媒体查询:
@media (prefers-color-scheme: dark) { :root { --bg: #121212; } },再用var(--bg)配合color.contrast-color()函数处理文字色
最容易被忽略的是:lighten()/darken() 在深色背景下会严重降低对比度,color.contrast-color($base) 返回的黑白值虽安全,但缺乏灰阶过渡——真要精细控制,得预设一套深色 palette map,而不是靠函数实时算。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











