Sass 最佳实践 #
命名规范 #
变量命名 #
scss
// 好:语义化、小写、连字符分隔
$primary-color: #3498db;
$font-size-base: 16px;
$spacing-unit: 8px;
$border-radius: 4px;
// 不好:无意义、驼峰、下划线
$blue: #3498db;
$fontSizeBase: 16px;
$spacing_unit: 8px;
映射键命名 #
scss
// 好:层级清晰
$colors: (
brand: (
primary: #3498db,
secondary: #2ecc71
),
semantic: (
success: #2ecc71,
danger: #e74c3c
)
);
// 不好:扁平结构
$color-brand-primary: #3498db;
$color-brand-secondary: #2ecc71;
Mixin 命名 #
scss
// 好:动词开头,描述行为
@mixin flex-center { }
@mixin truncate-text($lines) { }
@mixin respond-to($breakpoint) { }
// 不好:名词或不清晰
@mixin center { }
@mixin text($lines) { }
@mixin media($bp) { }
函数命名 #
scss
// 好:描述返回值
@function get-color($name) { }
@function calculate-rem($px) { }
@function strip-unit($value) { }
// 不好:不清晰
@function color($name) { }
@function rem($px) { }
@function unit($value) { }
占位符命名 #
scss
// 好:描述基础样式
%button-base { }
%card-base { }
%form-element { }
// 不好:无意义
%btn { }
%c { }
%form { }
代码组织 #
文件结构 #
text
sass/
│
├── abstracts/ # 抽象层(不直接输出样式)
│ ├── _variables.scss # 变量
│ ├── _mixins.scss # 混合宏
│ ├── _functions.scss # 函数
│ └── _index.scss # 转发
│
├── base/ # 基础样式
│ ├── _reset.scss # 重置样式
│ ├── _typography.scss # 排版
│ └── _base.scss # 基础元素
│
├── components/ # 组件
│ ├── _buttons.scss
│ ├── _cards.scss
│ └── _forms.scss
│
├── layout/ # 布局
│ ├── _header.scss
│ ├── _footer.scss
│ └── _grid.scss
│
├── pages/ # 页面特定样式
│ ├── _home.scss
│ └── _about.scss
│
├── themes/ # 主题
│ └── _default.scss
│
└── main.scss # 主入口
主文件组织 #
scss
// main.scss
// 1. 配置(在其他模块之前)
@use 'abstracts' as *;
// 2. 基础样式
@use 'base';
// 3. 布局
@use 'layout';
// 4. 组件
@use 'components';
// 5. 页面
@use 'pages';
// 6. 主题
@use 'themes';
组件文件结构 #
scss
// _button.scss
// 1. 依赖
@use '../abstracts' as *;
// 2. 变量
$button-padding: 10px 20px;
$button-radius: 4px;
// 3. 基础样式
.button {
// 布局
display: inline-block;
// 盒模型
padding: $button-padding;
// 视觉
background-color: map-get($colors, primary);
border-radius: $button-radius;
// 排版
font-size: 14px;
text-align: center;
// 其他
cursor: pointer;
transition: all 0.2s;
}
// 4. 变体
.button--primary { }
.button--secondary { }
.button--large { }
.button--small { }
// 5. 状态
.button:hover { }
.button:active { }
.button:disabled { }
选择器规范 #
控制嵌套深度 #
scss
// 好:最多 3 层
.container {
.item {
.title {
font-size: 20px;
}
}
}
// 不好:嵌套过深
.page {
.content {
.section {
.article {
.paragraph {
.link {
// 太深了
}
}
}
}
}
}
使用 BEM 命名 #
scss
// 好:BEM 命名
.card {
&__header { }
&__body { }
&__footer { }
&--featured { }
&--compact { }
}
// 不好:深层嵌套
.card {
.header {
.title {
.text {
// ...
}
}
}
}
避免过度使用 & #
scss
// 好:适度使用
.button {
&:hover { }
&--primary { }
}
// 不好:过度使用
.button {
&__wrapper {
&__container {
&__content {
// ...
}
}
}
}
变量管理 #
集中管理 #
scss
// _variables.scss
// 颜色
$colors: (
brand: (
primary: #3498db,
secondary: #2ecc71
),
semantic: (
success: #2ecc71,
warning: #f39c12,
danger: #e74c3c
)
);
// 间距
$spacing: (
sm: 8px,
md: 16px,
lg: 24px
);
// 字体
$font-family: (
base: ('Helvetica Neue', Arial, sans-serif),
heading: ('Georgia', serif)
);
使用映射组织 #
scss
// 好:使用映射
$colors: (
primary: #3498db,
secondary: #2ecc71
);
.element {
color: map-get($colors, primary);
}
// 不好:分散变量
$color-primary: #3498db;
$color-secondary: #2ecc71;
避免魔法数字 #
scss
// 好:使用变量
$border-radius: 4px;
$transition-duration: 0.2s;
.button {
border-radius: $border-radius;
transition: all $transition-duration;
}
// 不好:硬编码
.button {
border-radius: 4px;
transition: all 0.2s;
}
Mixin 最佳实践 #
单一职责 #
scss
// 好:职责单一
@mixin truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@mixin visually-hidden {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
}
// 不好:职责过多
@mixin text-utilities {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
color: #333;
}
提供默认值 #
scss
// 好:有默认值
@mixin flex-center($direction: row) {
display: flex;
flex-direction: $direction;
justify-content: center;
align-items: center;
}
// 不好:无默认值
@mixin flex-center($direction) {
display: flex;
flex-direction: $direction;
justify-content: center;
align-items: center;
}
使用 @content #
scss
// 好:使用 @content 提供灵活性
@mixin respond-to($breakpoint) {
@media (min-width: $breakpoint) {
@content;
}
}
.container {
@include respond-to(768px) {
width: 750px;
}
}
性能优化 #
避免过度生成 #
scss
// 好:按需生成
$breakpoints: (
sm: 576px,
md: 768px,
lg: 992px
);
@each $name, $value in $breakpoints {
@media (min-width: $value) {
.hidden-#{$name} {
display: none;
}
}
}
// 不好:过度生成
@for $i from 1 through 100 {
.mt-#{$i} {
margin-top: $i * 1px;
}
}
合理使用 @extend #
scss
// 好:使用占位符
%button-base {
display: inline-block;
padding: 10px 20px;
}
.btn-primary {
@extend %button-base;
background-color: blue;
}
.btn-secondary {
@extend %button-base;
background-color: gray;
}
// 不好:使用类选择器
.button-base {
display: inline-block;
padding: 10px 20px;
}
减少嵌套 #
scss
// 好:扁平结构
.card__header { }
.card__body { }
.card__footer { }
// 不好:深层嵌套
.card {
.header { }
.body { }
.footer { }
}
可维护性 #
注释规范 #
scss
// ============================================
// 文件说明
// ============================================
// --------------------------------------------
// 变量定义
// --------------------------------------------
$primary-color: #3498db;
// --------------------------------------------
// 基础样式
// --------------------------------------------
.button {
// 基础样式
display: inline-block;
// 状态样式
&:hover {
opacity: 0.8;
}
}
// TODO: 添加禁用状态样式
// FIXME: 修复移动端显示问题
// NOTE: 注意兼容性问题
文档注释 #
scss
/// 获取颜色值
/// @param {String} $name - 颜色名称
/// @param {String} $variant [base] - 颜色变体
/// @return {Color} 颜色值
/// @example
/// color: get-color(primary);
/// color: get-color(primary, light);
@function get-color($name, $variant: base) {
@return map-deep-get($colors, $name, $variant);
}
错误处理 #
scss
@function get-color($name) {
@if not map-has-key($colors, $name) {
@error "Color '#{$name}' not found in $colors map. " +
"Available colors: #{map-keys($colors)}";
}
@return map-get($colors, $name);
}
代码风格 #
属性顺序 #
scss
.element {
// 1. 定位
position: absolute;
top: 0;
right: 0;
z-index: 10;
// 2. 盒模型
display: flex;
width: 100px;
height: 100px;
margin: 10px;
padding: 10px;
// 3. 排版
font-size: 14px;
line-height: 1.5;
color: #333;
text-align: center;
// 4. 视觉
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
// 5. 动画
transition: all 0.2s;
// 6. 其他
cursor: pointer;
}
空行和缩进 #
scss
// 好:合理的空行
.container {
width: 100%;
.item {
color: red;
}
.another-item {
color: blue;
}
}
// 不好:无空行
.container {
width: 100%;
.item {
color: red;
}
.another-item {
color: blue;
}
}
工具推荐 #
代码检查 #
json
// .stylelintrc
{
"extends": "stylelint-config-standard-scss",
"rules": {
"max-nesting-depth": 3,
"selector-class-pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$"
}
}
格式化 #
json
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"useTabs": false
}
自动前缀 #
json
// package.json
{
"browserslist": [
"> 1%",
"last 2 versions"
]
}
检查清单 #
代码质量 #
- [ ] 变量命名语义化
- [ ] 嵌套深度不超过 3 层
- [ ] 使用 BEM 命名规范
- [ ] 避免魔法数字
- [ ] 添加必要注释
性能 #
- [ ] 避免过度生成类
- [ ] 合理使用 @extend
- [ ] 减少选择器复杂度
- [ ] 压缩输出
可维护性 #
- [ ] 文件结构清晰
- [ ] 模块职责单一
- [ ] 使用设计令牌
- [ ] 错误处理完善
下一步 #
掌握了最佳实践后,继续学习 项目结构,了解大型项目的架构设计!
最后更新:2026-03-28