Lovi.space

前端工程

SCSS 工程化:从变量堆砌到可演进的样式系统

用 Design Tokens、Sass Modules 和语义化主题,让视觉系统在扩展时仍保持一致与可维护。

·1 min read
#SCSS#CSS#Design Tokens#前端

核心洞察:SCSS 不是让 CSS 写得更花,而是让重复的视觉决策拥有结构、边界和稳定的命名。 当霓虹港从单个看板扩展到告警、设备、工单三套页面时,最危险的不是颜色不够炫,而是每个组件都开始复制一份蓝色、阴影、圆角和媒体查询。短期快,长期每次主题调整都会变成全仓搜索。

两类变量解决两类问题

CSS Custom Properties 适合运行时变化:深浅主题、用户偏好、组件状态。SCSS 变量、Map 与 Mixin 适合构建时组织:断点、色阶、重复模式和批量生成。不要用 SCSS 变量处理必须在浏览器中动态切换的主题。

$breakpoints: (sm: 640px, md: 840px);
:root {
--surface: #ffffff;
--text: #172033;
--brand: #5b5cf6;
}
[data-theme='dark'] {
--surface: #171d35;
--text: #e9edff;
}

组件只消费语义 token:var(--surface)var(--text),而不是直接写品牌色。这样同一个按钮在主题切换后仍拥有正确语义。

Token 应有层级

基础 token 描述原始色阶、尺寸和时间,例如 --violet-500;语义 token 描述用途,例如 --color-info--surface-raised;组件 token 描述具体部件,例如 --alert-card-border。层级越靠下,越不应被全局随意引用。

层级 回答的问题 示例
基础 有哪些原材料 色阶、间距、字号
语义 这个值代表什么 成功色、边界色、正文色
组件 某部件如何表达 卡片阴影、按钮背景
## Module 与 BEM 的边界 使用 `@use` 替代旧式全局 `@import`,让每个样式文件显式声明依赖。BEM 仍适合表达组件内部结构,但嵌套不应超过两三层;过深选择器会把 DOM 结构变成样式 API,稍改标记就连锁失效。 ```scss .alert-card { background: var(--surface); border: 1px solid var(--alert-card-border);

&__title { color: var(—text); } &—critical { —alert-card-border: var(—color-danger); } }

这里修饰符只改变组件 token,而非复制一整套规则。这正是语义变量带来的可扩展性。
## 炫彩也要有约束
渐变、光晕和动效属于强调层,不应承担信息唯一编码。正文、状态与边界必须保持足够对比度;`prefers-reduced-motion` 应关闭非必要漂浮与闪烁。视觉效果服务于层级和注意力,而不是抢走阅读本身。
## 结语
一个可演进的样式系统,最终让设计变化变成改 token,而非修改几十个组件。SCSS 提供组织能力,CSS Variables 提供运行时弹性;两者各司其职,页面才能既炫彩又稳定。

读到这里,说明你也在认真对待这个问题。

讨论与反应

⌘ K