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