五个可以用 CSS 替代的 Sass 特性
如果你已经使用 Sass 多年,你一定清楚它带来的价值:变量、嵌套、颜色函数,以及更清晰的样式表组织方式。但现代 CSS 已经悄然迎头赶上。曾经需要预处理器和构建步骤才能实现的若干特性,如今已经成为原生支持、兼容良好、可投入生产的标准能力。
这并不是要你完全放弃 Sass。在编译时逻辑、循环、map 和复杂函数方面,Sass 依然占据优势。但如果你维护 Sass 依赖主要是为了下面这五个特性,那么原生 CSS 很可能已经足以替代它。
核心要点
- CSS 自定义属性、原生嵌套、
color-mix()、@layer和@property已经覆盖了开发者过去依赖 Sass 处理的大量日常场景。 - 自定义属性在运行时解析,这使其在主题切换和动态 UI 方面比 Sass 变量更为强大。
@layer提供了显式的层叠控制,消除了 Sass 自身无法解决的特异性 hack 问题。- 在编译时逻辑方面(如循环、map、条件判断和自定义函数),Sass 仍然具有不可替代的价值。
1. CSS 自定义属性替代 Sass 变量
Sass:
$primary: #3498db;
.button { background: $primary; }
原生 CSS:
:root { --primary: #3498db; }
.button { background: var(--primary); }
CSS 自定义属性在现代浏览器中已得到广泛支持,并能做到 Sass 变量做不到的事情:它们在运行时解析,而非编译时。这意味着你可以通过 JavaScript 更新它们、将其作用域限定在某个组件,或在媒体查询中覆盖它们。在主题切换和动态 UI 方面,它们比 $variables 更具能力。
权衡之处:当你需要某个值仅存在于构建时,或者你要把值传入 CSS 无法原生表达的循环和条件中时,Sass 变量仍然有用。
2. 原生 CSS 嵌套替代 Sass 嵌套
Sass:
.card {
padding: 1rem;
&:hover { background: #f5f5f5; }
.card__title { font-size: 1.25rem; }
}
原生 CSS:
.card {
padding: 1rem;
&:hover { background: #f5f5f5; }
& .card__title { font-size: 1.25rem; }
}
CSS 嵌套如今已在现代浏览器中得到广泛支持。其语法与 Sass 几乎完全一致,不过出于清晰性考虑,建议在嵌套的类型选择器或类选择器前加上 & 前缀。原生嵌套由浏览器解析,内部采用类似 :is() 的特异性行为,因此并非 Sass 的完美克隆,但对于大多数组件级样式而言,差异微乎其微。如果你使用 Sass 仅仅是为了嵌套,这是最容易替换的特性。
3. color-mix() 替代 Sass 颜色函数
Sass:
$primary: #3498db;
.button { background: darken($primary, 10%); }
原生 CSS:
:root { --primary: #3498db; }
.button { background: color-mix(in srgb, var(--primary) 80%, black); }
color-mix() 已在当前主流浏览器中获得广泛支持,允许你从单一基础色派生出更亮、更暗及混合后的变体。它并不是 darken() 或 lighten() 的一对一替代——后者在 HSL 空间中调整亮度,而 color-mix() 是混合两种颜色——但对于设计系统中的大多数实际用例而言,它能覆盖同样的需求。如果想更接近基于 HSL 的调整效果,你可以在 hsl 颜色空间中混合:color-mix(in hsl, var(--primary), black 10%)。
Discover how at OpenReplay.com.
4. @layer 替代特异性变通方案
Sass 开发者经常需要编写复杂的选择器结构来管理特异性。CSS @layer 现已在现代浏览器中得到广泛支持,让你能够显式控制层叠顺序,无需借助特异性 hack:
@layer base, components, utilities;
@layer base { a { color: blue; } }
@layer utilities { .text-red { color: red; } }
工具类样式总能胜过基础样式——并非因为选择器权重,而是因为层级顺序。在层叠管理方面,这是一个比 Sass 所能提供的任何方案都更优雅的解决方式。
5. @property 替代类型化变量的变通方案
@property 现已在当前主流现代浏览器中获得支持,允许你为自定义属性注册类型、初始值和继承行为:
@property --hue {
syntax: '<number>';
initial-value: 220;
inherits: false;
}
这使得自定义属性的动画化成为可能,并能防止意外的继承——这是普通 CSS 自定义属性自身做不到的。本特性的浏览器支持比本文中其他特性更新,因此在生产环境大量使用前,请先检查你的目标浏览器兼容情况。
Sass 仍然更胜一筹之处
原生 CSS 没有 @each、@for、@if 或复杂 @function 逻辑的等价物。如果你的 Sass 用于生成工具类、以编程方式构建间距比例,或包含条件输出,那么请保留 Sass。另外请注意,Sass 的 @import 已被废弃——请改用 @use 和 @forward 模块系统。
总结
在变量、嵌套、颜色处理、层叠控制和类型化属性方面,现代 CSS 已经足以应对许多日常样式任务。审视一下你实际使用 Sass 来做什么。你可能会发现,构建步骤所解决的问题已经比过去少了很多。在编程逻辑方面,Sass 仍有其用武之地;但对于日常样式需求,原生 CSS 已经填平了差距。
常见问题
不一定。如果你的 Sass 配置稳定,完整迁移很少值得付出相应努力。相反,可以审视一下你实际依赖的是哪些特性。如果大部分用途是变量、嵌套和基础颜色调整,你可以将新组件逐步迁移到原生 CSS,同时保留 Sass 用于遗留文件以及循环、map 等编程逻辑。
可以。Sass 编译为 CSS,因此自定义属性、嵌套、color-mix、layer 和 property 等原生特性可以与 Sass 并存而不冲突。许多团队将 Sass 用于构建时逻辑,将原生 CSS 用于主题等运行时需求。
自定义属性、color-mix() 和 @layer 在现代浏览器中已得到广泛支持,原生嵌套的支持现在也已普及。@property 较新,因此在生产环境中重度依赖之前,请先检查你的目标浏览器情况。caniuse.com 等网站可用于验证特性是否符合你的受众需求。
它可以降低构建复杂度并去除一个编译步骤,从而加快开发反馈速度。运行时性能差异通常可以忽略不计,因为 Sass 最终会编译为普通 CSS。更大的收益体现在工程层面:更少的依赖、更简单的工具链,以及无需重新构建即可通过 JavaScript 或媒体查询动态更新数值的能力。
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..