写了三年 Sass,每次想复用一段样式块都要靠 mixin 加 include——今天 CSS 自己会了
做过设计系统的都知道,组件库里最高频的诉求不是变量,是样式块复用:按钮的基础样式要复用,卡片的交互状态要复用,表单的错误提示也要复用。Sass 的 @mixin 把这件事做到了极致,但代价是你得维护一套编译链。
今天这件事在浏览器里原生化了。
Chrome 和 Edge 已经开始在 Experimental Web Platform Features 标志下实验 CSS 原生 Mixins,语法长这样:
/* 定义一个 mixin */
@mixin --card-base(--bg: white, --radius: 8px) {
@result {
background: var(--bg);
border-radius: var(--radius);
padding: 1rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
}
/* 在选择器里引用 */
.card-default {
@apply --card-base();
}
.card-dark {
@apply --card-base(--bg: #1a1a1a, --radius: 12px);
}
参数、默认值、条件逻辑都有,输出的是直接可用的 CSS 声明块,不再需要任何编译步骤。
对比一下 Sass 的方案:
| Sass | 原生 CSS | |
|---|---|---|
| 参数支持 | ✅ | ✅(通过 CSS 自定义属性实现) |
| 默认值 | ✅ | ✅ |
| 构建依赖 | 需要 Sass 编译器 | 不需要 |
| 调试体验 | 源码映射复杂 | 直接对应 CSS 源码 |
| 零运行时成本 | ❌(仍有编译开销) | ✅(纯 CSS,无任何开销) |
实际落地最关键的问题是:目前 Chrome/Edge 还需开启实验标志,Firefox 在跟进中。所以生产环境要用,得套一层渐进增强:
/* 基线:不用 mixin,直接写 */
.card {
background: white;
border-radius: 8px;
padding: 1rem;
}
/* 渐进增强:有 mixin 的浏览器会走这条 */
@supports (background: var(--x)) {
.card {
@apply --card-base();
}
}
目前阶段 polyfill 方案已经有社区在做:css-mixin-polyfill 这个包支持构建时转换,可以把 @mixin/@apply 语法在构建阶段转成普通 CSS,生产环境直接用,对 Safari 和不支持的浏览器零影响。
从工程视角看这件事的价值不只是语法:它意味着 CSS 终于有了一个原生的复用原语,设计系统的样式块不再必须依赖预处理器,整个构建链路可以再简化一层。对于已经有 Sass 的团队,这是增量优化;对于新项目,可以直接押注原生方案等待浏览器全面支持。
下一步:本地开 Chrome 标志测一下语法,确认行为符合预期;同时用 css-mixin-polyfill 在构建层做生产兜底,等浏览器稳定支持后平滑迁移。
评论区
0 条评论
登录后可评论。