Sass 控制指令 #
什么是控制指令? #
控制指令允许你在样式中使用条件判断和循环,实现更复杂的样式逻辑。Sass 提供了四种控制指令:
| 指令 | 用途 |
|---|---|
| @if | 条件判断 |
| @for | 数值循环 |
| @each | 列表/映射遍历 |
| @while | 条件循环 |
@if 条件判断 #
基本语法 #
scss
@if condition {
// 条件为真时执行
}
单条件 #
scss
$theme: dark;
body {
@if $theme == dark {
background-color: #1a1a1a;
color: #ffffff;
}
}
@else if 和 @else #
scss
$size: large;
.button {
@if $size == small {
padding: 5px 10px;
font-size: 12px;
} @else if $size == medium {
padding: 10px 20px;
font-size: 14px;
} @else if $size == large {
padding: 15px 30px;
font-size: 16px;
} @else {
padding: 10px 20px;
font-size: 14px;
}
}
在混合宏中使用 #
scss
@mixin theme($mode: light) {
@if $mode == dark {
background-color: #1a1a1a;
color: #ffffff;
} @else {
background-color: #ffffff;
color: #333333;
}
}
body {
@include theme(dark);
}
在函数中使用 #
scss
@function get-color($type, $variant: base) {
$colors: (
primary: (
base: #3498db,
light: #5dade2,
dark: #2980b9
),
secondary: (
base: #2ecc71,
light: #58d68d,
dark: #27ae60
)
);
$color-map: map-get($colors, $type);
@if $variant == light {
@return map-get($color-map, light);
} @else if $variant == dark {
@return map-get($color-map, dark);
} @else {
@return map-get($color-map, base);
}
}
.button {
background-color: get-color(primary);
border-color: get-color(primary, dark);
}
@for 循环 #
语法格式 #
scss
// 从 start 到 end(包含 end)
@for $var from start through end { }
// 从 start 到 end(不包含 end)
@for $var from start to end { }
through vs to #
scss
// through:包含结束值
@for $i from 1 through 3 {
.item-#{$i} {
width: $i * 100px;
}
}
// 生成 .item-1, .item-2, .item-3
// to:不包含结束值
@for $i from 1 to 3 {
.item-#{$i} {
width: $i * 100px;
}
}
// 生成 .item-1, .item-2
生成网格系统 #
scss
$columns: 12;
@for $i from 1 through $columns {
.col-#{$i} {
width: percentage($i / $columns);
}
}
// 编译后
.col-1 { width: 8.333%; }
.col-2 { width: 16.667%; }
.col-3 { width: 25%; }
// ... 直到 .col-12
生成间距类 #
scss
@for $i from 0 through 5 {
.mt-#{$i} { margin-top: $i * 8px; }
.mb-#{$i} { margin-bottom: $i * 8px; }
.ml-#{$i} { margin-left: $i * 8px; }
.mr-#{$i} { margin-right: $i * 8px; }
.p-#{$i} { padding: $i * 8px; }
}
// 编译后
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
// ...
生成字体大小 #
scss
@for $i from 1 through 6 {
.text-#{$i} {
font-size: 2rem - ($i - 1) * 0.25rem;
}
}
// 编译后
.text-1 { font-size: 2rem; }
.text-2 { font-size: 1.75rem; }
.text-3 { font-size: 1.5rem; }
.text-4 { font-size: 1.25rem; }
.text-5 { font-size: 1rem; }
.text-6 { font-size: 0.75rem; }
生成延迟动画 #
scss
@for $i from 1 through 5 {
.delay-#{$i} {
animation-delay: $i * 0.1s;
}
}
// 编译后
.delay-1 { animation-delay: 0.1s; }
.delay-2 { animation-delay: 0.2s; }
.delay-3 { animation-delay: 0.3s; }
.delay-4 { animation-delay: 0.4s; }
.delay-5 { animation-delay: 0.5s; }
@each 遍历 #
遍历列表 #
scss
$colors: red, green, blue;
@each $color in $colors {
.text-#{$color} {
color: $color;
}
.bg-#{$color} {
background-color: $color;
}
}
// 编译后
.text-red { color: red; }
.bg-red { background-color: red; }
.text-green { color: green; }
.bg-green { background-color: green; }
.text-blue { color: blue; }
.bg-blue { background-color: blue; }
遍历映射 #
scss
$colors: (
primary: #3498db,
secondary: #2ecc71,
danger: #e74c3c,
warning: #f39c12
);
@each $name, $color in $colors {
.btn-#{$name} {
background-color: $color;
&:hover {
background-color: darken($color, 10%);
}
}
}
// 编译后
.btn-primary {
background-color: #3498db;
}
.btn-primary:hover {
background-color: #2980b9;
}
// ...
遍历嵌套列表 #
scss
$sizes: (
(small, 10px, 12px),
(medium, 15px, 14px),
(large, 20px, 16px)
);
@each $name, $padding, $font-size in $sizes {
.btn-#{$name} {
padding: $padding;
font-size: $font-size;
}
}
// 编译后
.btn-small { padding: 10px; font-size: 12px; }
.btn-medium { padding: 15px; font-size: 14px; }
.btn-large { padding: 20px; font-size: 16px; }
生成图标类 #
scss
$icons: (
home: "\e800",
user: "\e801",
settings: "\e802",
search: "\e803"
);
@each $name, $code in $icons {
.icon-#{$name}::before {
content: $code;
font-family: "iconfont";
}
}
// 编译后
.icon-home::before { content: "\e800"; font-family: "iconfont"; }
.icon-user::before { content: "\e801"; font-family: "iconfont"; }
.icon-settings::before { content: "\e802"; font-family: "iconfont"; }
.icon-search::before { content: "\e803"; font-family: "iconfont"; }
生成断点样式 #
scss
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
@each $name, $value in $breakpoints {
@media (min-width: $value) {
.hidden-#{$name} {
display: none !important;
}
}
}
// 编译后
@media (min-width: 576px) {
.hidden-sm { display: none !important; }
}
@media (min-width: 768px) {
.hidden-md { display: none !important; }
}
// ...
@while 循环 #
基本语法 #
scss
@while condition {
// 循环体
}
基本示例 #
scss
$i: 1;
@while $i <= 5 {
.item-#{$i} {
width: $i * 20px;
}
$i: $i + 1;
}
// 编译后
.item-1 { width: 20px; }
.item-2 { width: 40px; }
.item-3 { width: 60px; }
.item-4 { width: 80px; }
.item-5 { width: 100px; }
生成字体大小 #
scss
$font-size: 2rem;
$i: 1;
@while $font-size >= 0.75rem {
.text-#{$i} {
font-size: $font-size;
}
$font-size: $font-size - 0.25rem;
$i: $i + 1;
}
// 编译后
.text-1 { font-size: 2rem; }
.text-2 { font-size: 1.75rem; }
.text-3 { font-size: 1.5rem; }
.text-4 { font-size: 1.25rem; }
.text-5 { font-size: 1rem; }
.text-6 { font-size: 0.75rem; }
注意事项 #
scss
// 警告:确保循环能够终止
$i: 1;
@while $i <= 10 {
// 必须更新条件变量
$i: $i + 1;
}
// 错误:无限循环
$i: 1;
@while $i <= 10 {
// 忘记更新 $i,会导致无限循环
}
组合使用 #
@if + @for #
scss
@for $i from 1 through 12 {
.col-#{$i} {
width: percentage($i / 12);
@if $i <= 6 {
float: left;
} @else {
float: right;
}
}
}
@each + @if #
scss
$colors: (
primary: #3498db,
secondary: #2ecc71,
danger: #e74c3c
);
@each $name, $color in $colors {
.btn-#{$name} {
background-color: $color;
@if $name == danger {
border: 2px solid darken($color, 20%);
}
}
}
嵌套循环 #
scss
$sizes: (sm, md, lg);
$directions: (t, b, l, r);
@each $size in $sizes {
@each $dir in $directions {
.m#{$dir}-#{$size} {
margin-#{$dir}: 10px;
}
}
}
// 编译后
.mt-sm { margin-top: 10px; }
.mb-sm { margin-bottom: 10px; }
.ml-sm { margin-left: 10px; }
.mr-sm { margin-right: 10px; }
// ...
实际应用示例 #
完整网格系统 #
scss
$columns: 12;
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
// 基础列
@for $i from 1 through $columns {
.col-#{$i} {
flex: 0 0 percentage($i / $columns);
max-width: percentage($i / $columns);
}
}
// 响应式列
@each $bp, $value in $breakpoints {
@media (min-width: $value) {
@for $i from 1 through $columns {
.col-#{$bp}-#{$i} {
flex: 0 0 percentage($i / $columns);
max-width: percentage($i / $columns);
}
}
}
}
完整间距系统 #
scss
$spacer: 1rem;
$spacers: (
0: 0,
1: $spacer * 0.25,
2: $spacer * 0.5,
3: $spacer,
4: $spacer * 1.5,
5: $spacer * 3
);
$properties: (
m: margin,
p: padding
);
$directions: (
t: top,
b: bottom,
l: left,
r: right,
x: (left, right),
y: (top, bottom)
);
@each $prop-key, $prop-value in $properties {
@each $spacer-key, $spacer-value in $spacers {
// 全方向
.#{$prop-key}-#{$spacer-key} {
#{$prop-value}: $spacer-value;
}
// 单方向
@each $dir-key, $dir-value in $directions {
@if type-of($dir-value) == list {
.#{$prop-key}#{$dir-key}-#{$spacer-key} {
@each $dir in $dir-value {
#{$prop-value}-#{$dir}: $spacer-value;
}
}
} @else {
.#{$prop-key}#{$dir-key}-#{$spacer-key} {
#{$prop-value}-#{$dir-value}: $spacer-value;
}
}
}
}
}
主题系统 #
scss
$themes: (
light: (
bg: #ffffff,
text: #333333,
primary: #3498db
),
dark: (
bg: #1a1a1a,
text: #ffffff,
primary: #5dade2
)
);
@mixin theme($theme-name) {
$theme: map-get($themes, $theme-name);
background-color: map-get($theme, bg);
color: map-get($theme, text);
.button {
background-color: map-get($theme, primary);
}
}
// 生成主题类
@each $name, $colors in $themes {
.theme-#{$name} {
@include theme($name);
}
}
最佳实践 #
1. 避免过度使用 #
scss
// 好:适度使用
@for $i from 1 through 5 {
.mt-#{$i} { margin-top: $i * 8px; }
}
// 不好:过度生成
@for $i from 1 through 100 {
.mt-#{$i} { margin-top: $i * 1px; }
}
2. 使用有意义的变量名 #
scss
// 好
@for $column from 1 through $total-columns {
.col-#{$column} { width: percentage($column / $total-columns); }
}
// 不好
@for $i from 1 through $n {
.col-#{$i} { width: percentage($i / $n); }
}
3. 结合映射使用 #
scss
// 好:使用映射配置
$colors: (primary: #3498db, secondary: #2ecc71);
@each $name, $color in $colors {
.text-#{$name} { color: $color; }
}
// 不好:硬编码
.text-primary { color: #3498db; }
.text-secondary { color: #2ecc71; }
下一步 #
掌握了控制指令后,继续学习 运算符,深入了解 Sass 的计算能力!
最后更新:2026-03-28