SCSS 仍被需要,是因为它解决构建期静态样式工程问题,专注设计系统层、主题配置、全局变量管理与样式复用;而 CSS-in-JS 处理组件级、运行时、状态驱动的样式逻辑,二者作用域不同,常共存使用。

SCSS 仍被需要,是因为它解决的是构建期静态样式工程问题
不是“CSS-in-JS 和 SCSS 谁替代谁”,而是它们作用域根本不同:CSS-in-JS 主要处理 组件级、运行时、状态驱动 的样式逻辑;SCSS 则专注在 设计系统层、主题配置、全局变量管理、样式复用与维护 这类构建期静态任务。很多团队同时用两者——styled-components 写 Button 的 disabled 状态,_variables.scss 定义整套色板和断点。
SCSS 的全局变量和 mixin 在 CSS-in-JS 中难以平替
CSS-in-JS 库(如 @emotion/css 或 styled-components)虽支持 JS 变量,但无法天然复用 SCSS 那套成熟的颜色函数(lighten($primary, 10%))、响应式 mixin(@include media-breakpoint-up(md))或设计 token 分发机制。这些能力依赖 SCSS 的编译期求值和 AST 操作,JS 运行时做不到等价表达。
- SCSS 的
$color-primary可被所有.scss文件直接消费,包括第三方 UI 组件的覆盖样式(如ant-design的override.scss) - Emotion 的
css函数若传入 JS 对象,lighten必须手写或引入polished,且无法参与构建期压缩/提取 - SCSS 的
@mixin clearfix是纯文本注入,零运行时开销;而用 JS 实现等效逻辑需额外函数封装、调用、类型检查
Vite + SCSS 仍是企业级主题切换最稳的组合
当项目需要多主题(light/dark/high-contrast)、多品牌(brand-a/brand-b)打包时,SCSS 的 @import + @use + configuration file 方案比 CSS-in-JS 的运行时 theme provider 更可控——主题差异在构建时就分离为不同 CSS 文件,不增加 JS 包体积,也不依赖 hydration 时机。
- SCSS 主题切换靠
theme-light.scss和theme-dark.scss分别@use "variables" with ($mode: light),输出两个独立 CSS - Emotion 的
useTheme需在每个组件内读取 context,主题变更触发全量 re-render,且 SSR 时必须确保服务端与客户端 theme 值严格一致 - Vite 中只需
preprocessorOptions.scss.additionalData注入变量,无需插件、无 Babel 依赖、无 cache 实例冲突风险
容易被忽略的关键点:CSS-in-JS 不处理 CSS 层的“抽象语法树”操作
SCSS 编译器能做 AST 级别的优化:自动提取重复声明、合并媒体查询、内联 @function 计算结果。这些是运行时 CSS-in-JS 根本不介入的环节。比如一个 @function get-spacing($level) 返回 calc(0.25rem * $level),SCSS 构建时就能展开为 0.5rem;而 JS 里写 padding: `${0.25 * level}rem`,既无法压缩,也无法被 PostCSS 插件识别。
立即学习“前端免费学习笔记(深入)”;
真正卡住迁移的不是语法习惯,而是你是否愿意把设计 token 的生成、品牌色的派生、断点系统的维护,全部从构建期搬到运行时,并承担随之而来的包体积、首屏延迟、SSR 复杂度上升——这些代价,SCSS 一句 @import "tokens" 就绕过去了。


















