SCSS(Sassy CSS)作为 CSS 预处理器的主流方案,凭借变量、嵌套、混合器等特性大幅提升 CSS 开发效率。本文将从 SCSS 基础语法到进阶技巧,再到 Vite+Vue3 项目的完整集成流程,帮你彻底学会 SCSS 的使用。

一、SCSS 基础认知​

1. 什么是 SCSS?​

SCSS 是 Sass(Syntactically Awesome Style Sheets)的语法扩展,兼容 CSS 语法(后缀为.scss),可通过编译器转换为标准 CSS。相比原生 CSS,其核心优势在于:​

  • 支持变量存储(颜色、尺寸等复用)​
  • 嵌套语法(简化层级结构)​
  • 代码复用机制(混合器、继承)​
  • 逻辑控制能力(条件、循环)​

2. 环境准备(单独使用 SCSS)​

若需单独编译 SCSS 文件,需先安装编译工具:

# 全局安装sass(SCSS官方编译器)
npm install -g sass

# 编译SCSS文件:sass 输入文件 输出文件
sass src/style.scss dist/style.css

# 实时监听文件变化(开发模式)
sass --watch src/style.scss:dist/style.css

二、SCSS 核心语法(必学)​

1. 变量(Variables)​

用于存储重复使用的值(颜色、字体、尺寸等),使用$定义,支持作用域。​

基础用法

// 定义变量(全局作用域)
$primary-color: #42b983; // Vue官方主题色
$font-size-base: 16px;
$border-radius: 4px;

// 使用变量
.button {
  background: $primary-color;
  font-size: $font-size-base;
  border-radius: $border-radius;
}

// 局部变量(仅在嵌套块内生效)
.card {
  $card-padding: 16px; // 局部变量
  padding: $card-padding;
  border: 1px solid #eee;
}

变量插值(字符串拼接)​

用于拼接选择器、属性名或 URL:

$prefix: btn;
$attr: color;

.#{$prefix}-primary { // 拼接选择器
  #{$attr}: $primary-color; // 拼接属性名
  background: url("../images/#{$prefix}-bg.png"); // 拼接URL
}

2. 嵌套(Nesting)​

简化 CSS 层级结构,避免重复书写父选择器,支持选择器嵌套、属性嵌套。​

选择器嵌套

// SCSS
.nav {
  width: 100%;
  ul {
    list-style: none;
    display: flex;
  }
  li {
    margin: 0 10px;
    a {
      color: #333;
      &:hover { // & 表示父选择器(此处为a)
        color: $primary-color;
      }
    }
  }
}

// 编译后的CSS
.nav { width: 100%; }
.nav ul { list-style: none; display: flex; }
.nav li { margin: 0 10px; }
.nav li a { color: #333; }
.nav li a:hover { color: #42b983; }

属性嵌套(针对带前缀的属性)

// SCSS
.box {
  font: { // 属性嵌套(font-*)
    size: 14px;
    weight: 500;
    family: "Roboto", sans-serif;
  }
  border: { // border-*
    width: 1px;
    color: #ddd;
    style: solid;
  }
}

// 编译后的CSS
.box {
  font-size: 14px;
  font-weight: 500;
  font-family: "Roboto", sans-serif;
  border-width: 1px;
  border-color: #ddd;
  border-style: solid;
}

3. 混合器(Mixins)​

用于复用代码块(支持参数),适合定义带逻辑的样式(如兼容性前缀、通用组件样式),使用@mixin定义,@include调用。​

无参数混合器

// 定义混合器(清除浮动)
@mixin clear-fix {
  &::after {
    content: "";
    display: table;
    clear: both;
  }
}

// 调用混合器
.header {
  @include clear-fix;
  height: 60px;
}

带参数混合器(支持默认值)

// 定义带参数的混合器(按钮样式)
@mixin button-style($bg: $primary-color, $text: #fff, $radius: $border-radius) {
  background: $bg;
  color: $text;
  border-radius: $radius;
  padding: 8px 16px;
  border: none;
  cursor: pointer;
  &:hover {
    opacity: 0.9;
  }
}

// 调用(使用默认参数)
.btn-primary {
  @include button-style;
}

// 调用(自定义参数)
.btn-danger {
  @include button-style(#ff4444, #fff, 6px);
}

4. 继承(Extend)​

用于复用选择器的样式(无参数),适合纯样式复用,使用@extend实现,编译后会合并选择器(比混合器更简洁)。

// 基础样式
.base-btn {
  padding: 8px 16px;
  border: none;
  border-radius: $border-radius;
  cursor: pointer;
}

// 继承基础样式并扩展
.btn-success {
  @extend .base-btn;
  background: #4caf50;
  color: #fff;
}

.btn-warning {
  @extend .base-btn;
  background: #ffc107;
  color: #333;
}

// 编译后的CSS(合并选择器)
.base-btn, .btn-success, .btn-warning {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.btn-success { background: #4caf50; color: #fff; }
.btn-warning { background: #ffc107; color: #333; }

三、SCSS 进阶特性​

1. 函数(Functions)​

SCSS 内置大量函数(颜色、数字、字符串等),也支持自定义函数(使用@function定义,@return返回值)。​

常用内置函数​

  • 颜色函数:lighten()(提亮)、darken()(加深)、rgba()(透明色)​
  • 数字函数:round()(四舍五入)、ceil()(向上取整)、floor()(向下取整)
// 颜色函数示例
.button {
  background: $primary-color;
  &:hover {
    background: lighten($primary-color, 10%); // 提亮10%
  }
  &:active {
    background: darken($primary-color, 10%); // 加深10%
  }
}

// 数字函数示例
.box {
  width: round(100.6px); // 101px
  height: ceil(200.1px); // 201px
}

自定义函数

// 自定义函数:px转rem(假设根字体16px)
@function px-to-rem($px) {
  @return $px / 16px * 1rem;
}

// 使用
.container {
  width: px-to-rem(1200px); // 75rem
  padding: px-to-rem(24px); // 1.5rem
}

2. 指令(Directives)​

条件判断(@if/@else if/@else)

@mixin text-size($size) {
  @if $size == "small" {
    font-size: 12px;
  } @else if $size == "medium" {
    font-size: 16px;
  } @else {
    font-size: 20px;
  }
}

.text {
  @include text-size("medium"); // 16px
}

循环(@for/@each)​

  • @for:按次数循环(from ... through包含终点,from ... to不包含终点)
// 生成1-5号字体样式
@for $i from 1 through 5 {
  .text-#{$i} {
    font-size: 12px + $i * 2px;
  }
}

// 编译后
.text-1 { font-size: 14px; }
.text-2 { font-size: 16px; }
// ... 直到.text-5
  • @each:遍历列表 / 映射
// 遍历列表
$colors: primary #42b983, danger #ff4444, success #4caf50;
@each $name, $color in $colors {
  .bg-#{$name} {
    background: $color;
  }
}

// 遍历映射(类似对象)
$font-sizes: (
  small: 12px,
  medium: 16px,
  large: 20px
);
@each $key, $value in $font-sizes {
  .text-#{$key} {
    font-size: $value;
  }
}

3. 模块化(@import/@use/@forward)​

SCSS 支持拆分文件(模块化),避免单文件过大。Vite+Vue3 项目中推荐使用@use(Sass 1.23.0+,替代旧版@import)。​

目录结构示例

src/
├── styles/
│   ├── _variables.scss   // 变量(下划线开头表示“局部文件”,不单独编译)
│   ├── _mixins.scss      // 混合器
│   └── main.scss         // 主文件(引入其他模块)

@use 用法(推荐)

// main.scss 中引入其他模块
@use "./variables" as vars; // 别名vars(可选,默认用文件名)
@use "./mixins";

// 使用模块中的变量和混合器
.body {
  background: vars.$primary-color; // 通过别名访问变量
  font-size: vars.$font-size-base;
}

.button {
  @include mixins.button-style(); // 访问混合器
}

@forward 用法(批量导出模块)

若需统一导出多个子模块,可创建_index.scss:

// styles/_index.scss
@forward "./variables"; // 导出variables模块
@forward "./mixins";    // 导出mixins模块

// 其他文件中只需引入_index.scss
@use "./styles" as styles;
.button {
  background: styles.$primary-color;
  @include styles.button-style();
}

四、Vite+Vue3 中引入 SCSS(核心实战)​

Vite 内置 SCSS 支持,无需额外安装编译器,只需简单配置即可在 Vue3 项目中使用。​

1. 项目初始化(若未创建项目)

# 创建Vue3项目(选择Default模板)
npm create vite@latest my-vue3-scss -- --template vue
# 进入项目目录
cd my-vue3-scss
# 安装依赖
npm install

2. 安装 SCSS 依赖​

Vite 需要sass依赖(SCSS 编译器),安装即可:

npm install sass -D

3. 两种引入方式(局部 / 全局)​

方式 1:单文件组件(SFC)局部引入​

在 Vue 组件的<style>标签中添加lang="scss",直接使用 SCSS 语法,或引入外部 SCSS 文件。

<!-- src/components/HelloSCSS.vue -->
<template>
  <div class="hello-scss">
    <h2 class="title">SCSS局部引入示例</h2>
    <button class="custom-btn">点击按钮</button>
  </div>
</template>

<script setup></script>

<style lang="scss">
// 1. 直接写SCSS(变量、嵌套)
$title-color: #333;
$btn-bg: #42b983;

.hello-scss {
  padding: 20px;
  .title {
    color: $title-color;
    font-size: 18px;
  }
  .custom-btn {
    background: $btn-bg;
    color: #fff;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    &:hover {
      opacity: 0.9;
    }
  }
}

// 2. 引入外部SCSS文件(局部生效)
// @import "../styles/_mixins.scss";
// .another-btn {
//   @include button-style(#ff4444);
// }
</style>

方式 2:全局引入(全局变量 / 混合器)​

若需在所有组件中直接使用全局变量(如主题色),无需每个组件单独引入,可通过 Vite 配置全局注入。​

步骤 1:创建全局 SCSS 文件

// src/styles/_variables.scss(全局变量)
$primary-color: #42b983;
$font-size-base: 16px;
$border-radius: 4px;

// src/styles/_mixins.scss(全局混合器)
@mixin button-style($bg: $primary-color, $text: #fff) {
  background: $bg;
  color: $text;
  padding: 8px 16px;
  border: none;
  border-radius: $border-radius;
}

步骤 2:配置 Vite(vite.config.js)​

通过css.preprocessorOptions.scss.additionalData注入全局 SCSS 代码:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' // 需引入path模块(Node内置)

export default defineConfig({
  plugins: [vue()],
  resolve: {
    // 配置路径别名(@指向src)
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  css: {
    preprocessorOptions: {
      scss: {
        // 注入全局变量和混合器(分号分隔多个文件)
        additionalData: `
          @use "@/styles/_variables.scss" as *;
          @use "@/styles/_mixins.scss" as *;
        `
        // 注:as * 表示不使用别名,直接访问变量(如$primary-color)
      }
    }
  }
})

步骤 3:在组件中直接使用全局 SCSS​

无需引入文件,直接使用全局变量和混合器:

<!-- src/components/GlobalSCSS.vue -->
<template>
  <button class="global-btn">全局SCSS按钮</button>
</template>

<script setup></script>

<style lang="scss">
.global-btn {
  // 直接使用全局变量和混合器
  @include button-style($primary-color, #fff);
  font-size: $font-size-base;
  margin-top: 10px;
}
</style>

4. 实战:用 SCSS 写响应式布局​

结合 SCSS 变量和混合器,快速实现响应式适配:

<template>
  <div class="responsive-container">
    <div class="card">响应式卡片</div>
  </div>
</template>

<script setup></script>

<style lang="scss">
// 定义响应式断点变量(全局变量可放_global.scss)
$breakpoints: (
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);

// 自定义响应式混合器
@mixin responsive($breakpoint) {
  $width: map-get($breakpoints, $breakpoint);
  @media (min-width: $width) {
    @content; // 插入使用时的样式
  }
}

.responsive-container {
  width: 90%;
  margin: 0 auto;

  // 使用响应式混合器
  @include responsive(sm) {
    width: 95%;
  }
  @include responsive(md) {
    width: 80%;
  }
  @include responsive(lg) {
    width: 70%;
  }

  .card {
    padding: 16px;
    background: #f5f5f5;
    @include responsive(md) {
      padding: 24px;
      border-radius: $border-radius;
    }
  }
}
</style>

五、常见问题与最佳实践

1. 常见问题​

  • 问题 1:全局样式不生效?​

检查 Vite 配置中additionalData的文件路径是否正确(推荐用@别名),且需重启 Vite 服务(配置修改后需重启)。​

  • 问题 2:SCSS 语法报错(如 “Undefined variable”)?​

确认变量已定义且引入正确,若使用@use需通过别名访问(如vars.$color),或加as *省略别名。​

  • 问题 3:Vite 安装 sass 后仍报错?​

尝试删除node_modules和package-lock.json,重新执行npm install,确保sass版本与 Vite 兼容(推荐sass@1.60.0+)。​

2. 最佳实践​

  1. 模块化拆分:按功能拆分 SCSS 文件(变量、混合器、组件样式、全局样式),避免单文件冗余。​
  2. 命名规范:变量名用kebab-case(如$font-size-base),混合器名用camelCase(如@mixin buttonStyle)。​
  3. 避免过度嵌套:嵌套层级不超过 3 层(防止编译后 CSS 选择器过长,影响性能)。​
  4. 优先用@use替代@import:@use支持作用域隔离,避免变量污染,是 Sass 官方推荐的模块化方案。​
  5. 全局样式管理:全局样式(如重置样式、主题色)放在src/styles/目录,通过 Vite 全局注入,组件样式写在 SFC 的<style lang="scss">中。​

六、总结​

SCSS 的核心价值在于 “提升 CSS 复用性与可维护性”,通过变量、嵌套、混合器等特性简化开发;而在 Vite+Vue3 中,只需安装sass并配置全局注入,即可无缝集成 SCSS。建议从实战出发,先在小组件中尝试变量和嵌套,再逐步使用混合器、模块化等进阶特性,最终形成符合项目需求的 SCSS 开发规范。​

若需进一步优化 SCSS 工作流,可结合 CSS Modules(避免样式冲突)或 CSS-in-JS 方案,但 SCSS 作为基础预处理器,仍是 Vue3 项目中样式管理的首选方案之一。

更多推荐