如今写CSS,各种新特性层出不穷,曾经让我们爱不释手的Sass,现在还有必要作为项目的标配吗?这篇就来掰扯掰扯,从个人折腾经验出发,看看什么时候可以跟Sass优雅分手,什么时候还得把它留在身边。
那些年Sass给的甜头
变量
刚开始用Sass那会儿,最爽的就是能定义变量了。配色、字体大小这些全局样式,只要在文件开头改一改,整个项目都能同步更新,再也不用满世界Ctrl+F找颜色值。比方说设定一个主题色$brand-primary: #3366cc,后面所有按钮、链接都直接用这个变量,哪天想换颜色,改这一个地方就行,别提多省心。
嵌套
嵌套这玩意儿,一开始觉得没啥,用上了就根本停不下来。以前写CSS,一个导航菜单得不停地重复写.nav、.nav li、.nav li a,现在直接套在一起,结构一目了然。
.nav {
background: #f5f5f5;
li {
display: inline-block;
a {
color: #333;
text-decoration: none;
}
}
}看着就像HTML的兄弟,维护的时候找关系贼方便,媒体查询也能塞进选择器里面,不用再翻到文件底部去找响应式代码。
函数与混入
还有那些好用的函数,比如darken()、lighten(),做按钮悬停效果简直神器。一个按钮背景色,直接background-color: darken($button-bg, 10%),深浅自动算,不用自己调半天色值。混入(mixin)也是,像清除浮动这种重复代码,写个@include clearfix就完事,省得每次都抄那几行。
原生CSS的逆袭
自定义属性
原生CSS现在有了自定义属性,也就是--开头的变量。这玩意儿比Sass变量还猛,因为它是动态的。Sass变量编译完就固定了,但自定义属性可以在媒体查询里重新赋值,还能用JavaScript动态改。
拿主题切换来说,在根元素定义--bg-color: #ffffff,暗色模式直接把:root换成--bg-color: #000000,样式不用改,页面自己就变。Sass变量做不到这种运行时切换,因为编译完就成死值了。去年给一个客户做亮色暗色双主题,靠着自定义属性,只改了几个变量就搞定,要是用Sass变量,得写两套样式或者多套类名,累得够呛。
原生嵌套
前几天做个人项目的记忆记录器原型,本来想着不用任何构建工具,纯手写CSS。写着写着发现,诶?这嵌套怎么也能跑?
.card {
background: white;
.card-title {
font-size: 1.2rem;
}
.card-body {
padding: 1rem;
}
}压根没报错,浏览器认识它。查了下才知道,原生CSS的嵌套规范这两年改了,以前非要加个&符号,现在跟Sass写法一样了。虽然有个小区别——Sass里可以玩&__title这种BEM风格的拼接,原生CSS不行。不过咱平时也没咋用这个花活,所以对日常开发来说,原生嵌套跟Sass嵌套基本没差。
颜色函数
以前用Sass的darken()调悬停色,现在原生CSS有了color-mix(),一样能干这事儿。比如给按钮背景变暗20%,写起来是这样的:
.button {
background-color: #3366cc;
&:hover {
background-color: color-mix(in oklab, #3366cc, #000000 20%);
}
}color-mix()可以混合两种颜色,第二个参数控制混合比例,效果跟darken()差不多。更牛的是,它还能跟自定义属性配合,动态调整混合色,这是Sass静态函数比不了的。
工具链让人头秃
依赖的坑
最近维护一个老WordPress站,要加点新样式。这项目之前用的Sass,编译工具是CodeKit。打开项目,配置半天,结果跑起来报错——Dart Sass新版语法跟旧代码不兼容,一堆警告。花十来分钟改了部分代码,还是有错误。最后实在懒得折腾,直接在WordPress模板里塞了段原生CSS解决问题。
类似的事情碰过好几次,工具链一复杂,维护成本就上去了。尤其是老项目,依赖的Sass版本、编译工具、Node版本,哪一环对不上就崩。有时候加个新样式,花在折腾工具上的时间比写代码还多,心里就嘀咕:图啥呢?
语法冲突
还有次写CSS Grid,用了minmax(min(200px, 100%), 1fr)这种现代语法,Sass非得把这当成数学表达式来算,结果是单位不兼容报错。后来搜了一圈,得用unquote()把函数包裹起来,让Sass跳过解析,直接输出给浏览器。
grid-template-columns: repeat(auto-fill, minmax(unquote("min(200px, 100%)"), 1fr));代码是能跑了,但看着别扭,写的时候还得记着避坑。如果不用Sass,直接写原生CSS,浏览器该认识就认识,哪来这些破事。
方案一:个人站点和新项目彻底甩掉Sass
- 检查现有代码
先把项目里用到的Sass特性列出来。主要是变量、嵌套、函数这些核心功能。变量看能不能换成自定义属性;嵌套基本可以直接搬;像darken()这种函数,用color-mix()替代;如果用了@extend或循环,可能需要手动复制或者换个写法。 - 逐个特性转换
- 变量替换:把Sass变量声明改成
--开头,放在:root里。$color-primary变成--color-primary: #3366cc。使用时color: var(--color-primary)。 - 嵌套迁移:直接删除原来的
.scss文件,把代码复制到.css文件里。Sass的嵌套规则原生CSS基本支持,但要留意那种拼接选择器(比如&-title)的写法,得拆开写。 - 函数替换:比如
darken($color, 20%)改成color-mix(in oklab, $color, #000000 20%)。lighten同理,混合白色就行。 - 混入处理:如果用了
@include clearfix,直接去查clearfix的原生实现,把代码写进去。或者干脆用display: flow-root这种新属性,效果一样,代码更少。
- 变量替换:把Sass变量声明改成
- 验证与清理
转换完跑一遍浏览器,看样式有没有崩。特别注意那些动态切换的样式,比如暗色模式,看看自定义属性有没有生效。没问题就把Sass的依赖文件、配置文件、编译脚本全删了,从此告别工具链。
方案二:大型项目渐进式迁移
- 新代码用原生CSS
从今天开始,所有新增的样式文件都用.css后缀,在里面放心用自定义属性、原生嵌套、color-mix()。旧代码不动,保证项目稳定运行。 - 共享变量互通
在Sass文件里定义变量,比如$color-primary,同时也在全局CSS里定义--color-primary: #3366cc。这样新旧代码都能拿到同一个色值。改颜色的时候改两个地方(或者用构建工具自动同步),至少保证一致。 - 逐步替换老功能
每次碰到老样式需要修改,顺手把那部分代码转成原生CSS。比如改某个组件,把它的Sass变量换成自定义属性,嵌套规则直接改写成原生写法,函数替换成color-mix()。不用一次改完,慢慢啃,啃到哪儿算哪儿。 - 评估收益决定终点
过个一年半载,看项目里原生CSS占比多少。如果老代码越来越少,新代码全是原生,那可以考虑彻底移除Sass。如果老代码太庞大,迁移成本太高,那就保持现状也行,反正Sass目前依然是成熟工具,不碍事。
拿手头的工作项目来说,代码库大得离谱,Sass深入骨髓,强行全量迁移根本不现实,老板也不会批这时间。所以策略就是维持现有Sass编译流程,但新开发的模块、组件全部原生CSS。两边一起跑,不打架,慢慢等老模块自然淘汰。
结尾
说到底,技术选型这事儿没有标准答案。小打小闹的个人项目,或者从头开始的新玩意儿,完全可以扔掉Sass,享受原生CSS的轻量快感。那些运行良好、代码量巨大的老系统,也没必要为了追新而大动干戈,Sass依然是靠谱的伙伴。
重要的是别被工具绑架。花时间去折腾配置、修复构建报错,不如多写几行能跑在浏览器里的代码。CSS现在发展得这么快,原生能做的事情越来越多,是时候重新审视那些曾经离不开的依赖了。
