好的,我现在需要回答用户关于如何使用SCSS + BEM + 设计token进行管理的问题。首先,我需要回忆这三个概念的特点以及如何结合使用。
首先,设计token(Design Tokens)是设计系统中的基础变量,比如颜色、字体大小、间距等,通常用变量表示。SCSS支持变量,可以方便地管理这些token。然后,BEM(Block Element Modifier)是一种CSS命名规范,用于提高类名的可维护性和复用性。结合SCSS的嵌套和混合器(mixin)可以更好地实现BEM结构。
接下来,我需要考虑如何将这三者结合。首先,设计token应该放在SCSS的变量文件中,比如variables.scss
,定义颜色、字体、间距等。然后,使用SCSS的嵌套语法来组织BEM的块(Block)、元素(Element)和修饰符(Modifier),确保类名符合BEM规范。同时,可以利用SCSS的mixin来复用BEM结构,减少重复代码。
然后,我需要具体说明步骤:
- 设计token管理:创建基础变量文件,定义颜色、字体、间距等全局token,可能还需要分主题的变量。
- BEM结构组织:使用SCSS的嵌套来编写BEM的块、元素和修饰符,确保类名结构清晰。
- 复用与维护:通过mixin或函数封装常用的BEM模式,结合设计token,提高代码复用性。
需要注意的点包括:避免过度嵌套导致的选择器权重问题,保持BEM类名的清晰,以及设计token的合理分类(如基础、组件、主题等)。
现在,我需要将这些思路整理成用户易懂的步骤,并给出示例代码,比如变量文件的结构、BEM类的SCSS写法,以及如何使用mixin来简化代码。同时,要确保示例符合用户项目中的SCSS使用习惯,比如用户项目中已经有@/assets/scss/variables.scss
,可以参考这个路径。
使用 SCSS + BEM + 设计 Token 进行样式管理时,可以通过以下步骤实现规范化和可维护的样式系统:
一、设计 Token 管理(基础层)
设计 Token 是设计系统的原子化变量(如颜色、字体、间距等),需集中管理以便全局复用和主题切换。建议按类型分类存储在 SCSS 变量文件中。
1. 创建 Token 文件
在项目的 @/assets/scss/
目录下创建 tokens
子目录,存放不同类型的设计 Token:
// 颜色 Token(基础色、品牌色、状态色等)
$color-primary: #2563eb; // 主色
$color-primary-light: #eff6ff; // 主色浅版
$color-success: #22c55e; // 成功色
$color-error: #ef4444; // 错误色
// 字体 Token(字号、字重、行高)
$font-size-base: 14px;
$font-size-lg: 16px;
$font-weight-medium: 500;
$line-height-base: 1.5;
// 间距 Token(边距、内边距)
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;
2. 全局引入 Token
在 vite.config.js
中配置 SCSS 全局注入(用户项目已有类似配置),确保所有 SCSS 文件可直接使用 Token:
css: {
preprocessorOptions: {
scss: {
additionalData: `
@import "@/assets/scss/tokens/_colors.scss";
@import "@/assets/scss/tokens/_typography.scss";
@import "@/assets/scss/tokens/_spacing.scss";
`
}
}
}
二、BEM 规范与 SCSS 结合(结构层)
BEM(Block-Element-Modifier)通过明确的命名规则解决 CSS 作用域混乱问题,SCSS 的嵌套语法可高效实现 BEM 结构。
1. BEM 命名规则
- Block(块):独立组件,如
card
、button
,类名用-
连接(或项目统一的分隔符)。 - Element(元素):块的子元素,用
__
连接块名,如card__title
。 - Modifier(修饰符):状态或变体,用
--
连接块/元素名,如card--disabled
或button__icon--large
。
2. SCSS 实现 BEM
利用 SCSS 的嵌套语法,按 BEM 结构编写样式,同时复用设计 Token:
// Block: card
.card {
padding: $spacing-md; // 使用间距 Token
border: 1px solid $color-primary-light; // 使用颜色 Token
border-radius: 8px;
// Element: card__title
&__title {
font-size: $font-size-lg; // 使用字体 Token
font-weight: $font-weight-medium;
color: $color-primary; // 使用颜色 Token
}
// Modifier: card--disabled(禁用状态)
&--disabled {
opacity: 0.6;
cursor: not-allowed;
// 嵌套 Element 的修饰符
&__title {
color: $color-text-disabled; // 假设已定义的 Token
}
}
}
三、高阶复用与维护(优化层)
通过 SCSS 的 mixin
、function
封装常用模式,减少重复代码,同时保持 BEM 规范。
1. 封装 BEM Mixin
定义通用 BEM Mixin,简化嵌套写法(可选,根据团队习惯):
@mixin bem($block) {
.#{$block} {
$current-block: $block;
@content;
}
// 子元素嵌套
@mixin element($element) {
&__#{$element} {
$current-element: $element;
@content;
}
}
// 修饰符嵌套
@mixin modifier($modifier) {
&--#{$modifier} {
@content;
}
}
}
2. 使用 Mixin 编写 BEM
@include bem('button') {
padding: $spacing-sm $spacing-md;
border-radius: 4px;
@include element('icon') {
margin-right: $spacing-sm;
font-size: $font-size-base;
}
@include modifier('primary') {
background: $color-primary;
color: white;
@include element('icon') {
color: white; // 覆盖图标颜色
}
}
}
四、注意事项
- 避免深度嵌套:SCSS 嵌套层级不超过 3 层(如
.block__element--modifier
),防止 CSS 选择器权重过高。 - 主题切换:设计 Token 可结合 CSS 变量(
var()
)实现动态主题,SCSS 预处理阶段生成基础样式,运行时通过 JS 切换变量值。 - 文档化:维护 Token 列表和 BEM 规范文档(如用 Style Dictionary 工具),确保团队协作一致性。
通过以上方式,SCSS 负责样式预处理和逻辑复用,BEM 保证类名规范和作用域清晰,设计 Token 实现原子化设计系统,三者结合可显著提升样式代码的可维护性和扩展性。