Sass(Syntactically Awesome Style Sheets)是 CSS 预处理器,扩展了 CSS 的语法,增加了变量、嵌套、混合、继承等特性,让 CSS 编写更高效、可维护。本文将从基础到进阶,结合实例讲解 Sass 核心知识点。
一、Sass 基础
1. 两种语法格式
Sass 有两种语法:
- SCSS(Sassy CSS) :兼容 CSS 语法,后缀
.scss,推荐使用。 - 缩进语法(Sass) :无大括号和分号,依赖缩进,后缀
.sass。
示例:
scss
// SCSS 语法(推荐)
$primary-color: #2c3e50;
body {
color: $primary-color;
}
// Sass 缩进语法
$primary-color: #2c3e50
body
color: $primary-color
2. 环境准备
需安装 Node.js,然后通过 npm 安装 Sass:
bash
npm install -g sass
编译命令:
bash
# 将 scss 文件编译为 css(实时监听变化)
sass --watch src/style.scss dist/style.css
二、核心特性(附实例)
1. 变量(Variables)
用于复用重复的值(颜色、字体、尺寸等),以 $ 开头。
基本用法
scss
// 定义变量
$primary-color: #3498db; // 主色调
$font-size-base: 16px; // 基础字体大小
$container-width: 1200px;// 容器宽度
// 使用变量
body {
color: $primary-color;
font-size: $font-size-base;
}
.container {
max-width: $container-width;
}
变量作用域
- 局部变量:仅在定义的块内生效;
- 全局变量:在全局定义,或用
!global标记。
scss
$global-color: #000; // 全局变量
.box {
$local-color: #f00 !global; // 转为全局变量
color: $global-color;
}
.text {
color: $local-color; // 可访问,因为已转为全局
}
变量默认值
用 !default 标记,仅在变量未定义时生效(适合组件开发)。
scss
$btn-color: #fff !default; // 若未定义 $btn-color,默认值生效
.btn {
background: $primary-color;
color: $btn-color;
}
2. 嵌套(Nesting)
模拟 HTML 层级结构,减少重复选择器,提高可读性。
基本嵌套
scss
// SCSS
.nav {
width: 100%;
background: #f5f5f5;
// 嵌套子选择器
.nav-item {
padding: 10px 15px;
float: left;
// 嵌套伪类
&:hover {
color: $primary-color;
}
// 嵌套属性(如 font、margin)
font: {
size: 14px;
weight: 500;
}
}
}
编译后 CSS:
css
.nav {
width: 100%;
background: #f5f5f5;
}
.nav .nav-item {
padding: 10px 15px;
float: left;
font-size: 14px;
font-weight: 500;
}
.nav .nav-item:hover {
color: #3498db;
}
父选择器 &
& 代表父级选择器,常用于伪类、伪元素、BEM 命名。
scss
.btn {
padding: 8px 16px;
&-primary { // 等同于 .btn-primary
background: #3498db;
}
&:active { // 等同于 .btn:active
transform: scale(0.98);
}
&::after { // 等同于 .btn::after
content: "";
display: inline-block;
}
}
3. 混合(Mixins)
可复用的代码块,支持传参,适合处理浏览器前缀、重复样式。
基本定义与使用
用 @mixin 定义,@include 引入。
scss
// 定义无参混合
@mixin clearfix {
&::after {
content: "";
display: table;
clear: both;
}
}
// 定义带参混合(可设默认值)
@mixin flex($direction: row, $align: center) {
display: flex;
flex-direction: $direction;
align-items: $align;
}
// 使用混合
.box {
@include clearfix;
@include flex(column, flex-start); // 传参覆盖默认值
}
.nav {
@include flex; // 使用默认值
}
编译后 CSS:
css
.box::after {
content: "";
display: table;
clear: both;
}
.box {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.nav {
display: flex;
flex-direction: row;
align-items: center;
}
处理浏览器前缀
scss
@mixin transform($property) {
-webkit-transform: $property;
-moz-transform: $property;
-ms-transform: $property;
transform: $property;
}
.box {
@include transform(rotate(30deg));
}
4. 继承(Extend)
用 @extend 继承另一个选择器的所有样式,适合共享基础样式。
基本用法
scss
// 基础样式
.base-btn {
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
border: none;
}
// 继承基础样式并扩展
.primary-btn {
@extend .base-btn;
background: #3498db;
color: #fff;
}
.secondary-btn {
@extend .base-btn;
background: #e74c3c;
color: #fff;
}
编译后 CSS:
css
.base-btn, .primary-btn, .secondary-btn {
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
border: none;
}
.primary-btn {
background: #3498db;
color: #fff;
}
.secondary-btn {
background: #e74c3c;
color: #fff;
}
占位符选择器(%)
仅被继承时生效,不会编译到 CSS 中,避免冗余。
scss
// 占位符选择器(不会单独编译)
%base-btn {
padding: 8px 16px;
border-radius: 4px;
}
.primary-btn {
@extend %base-btn;
background: #3498db;
}
编译后 CSS(无 %base-btn 相关样式):
css
.primary-btn {
padding: 8px 16px;
border-radius: 4px;
}
.primary-btn {
background: #3498db;
}
5. 运算(Operations)
支持数字(加减乘除)、颜色、字符串运算,单位会自动兼容。
数字运算
scss
$width: 100px;
$gap: 20px;
.box {
width: $width - 20; // 80px(单位自动补全)
margin: $gap / 2; // 10px
padding: $width * 0.5; // 50px
height: $width + 50%; // 100px + 50%(兼容不同单位)
}
颜色运算
支持 RGB/HSL 颜色的加减,或用内置函数调整。
scss
$base-color: #3498db;
.box {
// 颜色相加(R/G/B 分别加)
color: $base-color + #111; // #45a9ec
// 调整亮度
background: lighten($base-color, 10%); // 变亮10%
// 调整饱和度
border-color: saturate($base-color, 20%); // 饱和度+20%
}
字符串运算
用 + 拼接字符串。
scss
$prefix: "icon-";
.icon-home {
content: $prefix + "home"; // "icon-home"
}
6. 条件语句(Conditionals)
用 @if/@else if/@else 实现条件样式。
scss
$theme: dark; // 可切换 light/dark
body {
@if $theme == dark {
background: #000;
color: #fff;
} @else if $theme == light {
background: #fff;
color: #000;
} @else {
background: #f5f5f5;
color: #333;
}
}
7. 循环语句(Loops)
@for 循环
遍历数字范围,支持 from ... through(包含结束值)或 from ... to(不包含)。
scss
// 生成 .col-1 到 .col-12
@for $i from 1 through 12 {
.col-#{$i} { // #{$i} 插值语法,嵌入变量
width: (100% / 12) * $i;
}
}
编译后 CSS(部分):
css
.col-1 { width: 8.33333%; }
.col-2 { width: 16.66667%; }
/* ... */
.col-12 { width: 100%; }
@each 循环
遍历列表/映射(Map)。
scss
// 遍历列表
$colors: primary #3498db, secondary #e74c3c, success #2ecc71;
@each $name, $color in $colors {
.text-#{$name} {
color: $color;
}
}
// 遍历映射
$theme-map: (
dark: #000,
light: #fff,
gray: #f5f5f5
);
@each $key, $value in $theme-map {
.bg-#{$key} {
background: $value;
}
}
@while 循环
满足条件时循环。
scss
$i: 1;
@while $i <= 3 {
.item-#{$i} {
margin-left: $i * 10px;
}
$i: $i + 1;
}
8. 函数(Functions)
自定义可复用的计算逻辑,用 @function 定义,@return 返回值。
scss
// 定义函数:计算响应式字体大小
@function rem($px, $base: 16px) {
@return ($px / $base) * 1rem;
}
// 使用函数
body {
font-size: rem(16px); // 1rem
}
h1 {
font-size: rem(24px); // 1.5rem
}
9. 导入(Import)
Sass 的 @import 可导入其他 Sass 文件,且会合并编译,避免 CSS 多请求。
导入 SCSS 文件
scss
// _variables.scss(下划线开头的文件为「局部文件」,不会单独编译)
$primary-color: #3498db;
// style.scss
@import "variables"; // 无需后缀和下划线
body {
color: $primary-color;
}
导入 CSS 文件
若导入 .css 文件,会被编译为原生 CSS @import:
scss
@import "reset.css"; // 编译后为 @import url(reset.css);
三、进阶技巧
1. 插值语法(#{})
将变量嵌入选择器、属性名、字符串中,核心用法已在循环/混合中体现:
scss
$attr: color;
$selector: header;
#{$selector} {
border-#{$attr}: #333; // border-color: #333
#{$attr}: #666; // color: #666
}
2. 颜色函数
Sass 内置丰富的颜色处理函数:
rgb($r, $g, $b):生成 RGB 颜色;rgba($color, $alpha):添加透明度;lighten($color, $percent):提亮;darken($color, $percent):变暗;complement($color):补色;mix($color1, $color2, $weight):混合两种颜色。
scss
$color: #3498db;
.box {
color: rgba($color, 0.8); // 透明度 0.8
background: darken($color, 15%); // 变暗15%
border: 1px solid mix($color, #000, 20%); // 混合颜色
}
3. 列表与映射
列表(List)
空格/逗号分隔的值集合,类似数组:
scss
$fonts: "Roboto", "Arial", sans-serif;
$sizes: 12px 14px 16px;
// 取值(索引从1开始)
body {
font-family: nth($fonts, 1); // Roboto
font-size: nth($sizes, 3); // 16px
}
映射(Map)
键值对集合,类似对象:
scss
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px
);
// 遍历映射
@each $name, $width in $breakpoints {
@media (min-width: $width) {
.container-#{$name} {
max-width: $width;
}
}
}
四、最佳实践
- 文件拆分 :按功能拆分文件(
_variables.scss、_mixins.scss、_base.scss等),统一导入主文件; - 命名规范 :变量/混合名用小写+连字符(
$primary-color),占位符用%base-xxx; - 避免过度嵌套:嵌套层级不超过 3 层,防止编译后 CSS 选择器过深;
- 优先使用混合/继承:复用样式,减少冗余;
- 使用局部文件 :下划线开头的文件(
_xxx.scss)不会单独编译,避免生成无用 CSS。
五、总结
Sass 通过变量、嵌套、混合、继承等特性,解决了原生 CSS 复用性差、冗余度高的问题。掌握本文的核心知识点(尤其是变量、嵌套、混合、循环),能大幅提升 CSS 开发效率和可维护性。实际项目中,建议结合模块化拆分和规范命名,充分发挥 Sass 的优势。