配了八年 Sass,每次写 @mixin 都要靠 node-sass 编译——今天微软把这件事彻底搬进了浏览器
配了八年 Sass,每次写 @mixin 都要靠 node-sass 编译。今天发现微软把这件事彻底搬进了浏览器——Chrome Platform Status 上悄悄更新了状态,@mixin 正式进入 Prototype 阶段。
这件事意味着什么?你的样式复用,以后不用装任何预处理器了。
原生 @mixin 是什么
和 Sass 的 @mixin 一个名字,但运行在浏览器里。
定义一个可复用的样式块:
@mixin --card-base {
border-radius: 12px;
padding: 1.5rem;
background: white;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
在任意选择器里引用:
.card-primary {
@apply --card-base;
}
.card-elevated {
@apply --card-base;
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
这和 Sass 的 @include 逻辑完全一样,但跑在 CSS 层面,不跑构建。
它和 Sass 的区别在哪里
Sass 的 @mixin 是编译时展开——你写的是一套语法,构建工具把它替换成普通 CSS,再交给浏览器。原 @mixin 是运行时展开——浏览器自己认识这套语法,直接执行。
区别不只是「少装一个包」,而是三个质的不同:
一,可以写条件逻辑。
@mixin --responsive-padding {
padding: 1rem;
@media (min-width: 768px) {
padding: 2rem;
}
}
Sass 也能写 @media,但它在编译时决定「这段 CSS 写不写进去」。原生 @mixin 是在运行时由浏览器根据实际视口判断,Sass 做不到这一点。
二,可以接收参数并做类型检查。
@mixin --gradient-linear(
--color-1 type(color),
--color-2 type(color),
--angle type(angle)
) {
background: linear-gradient(
var(--angle, to bottom),
var(--color-1),
var(--color-2)
);
}
.hero-gradient {
@apply --gradient-linear(orangered, goldenrod, 45deg);
}
类型检查是 CSS 规范自己带的,不是构建工具加的。传错类型浏览器直接报错,不像 Sass 那样静默忽略。
三,私有变量不会污染元素。
@mixin --card(--size) {
--internal-size: calc(var(--size) * 1px);
width: var(--internal-size);
}
–internal-size 这个变量只存在于 mixin 内部,不会被设置到实际元素上,不会有副作用。Sass 的变量会直接渗透到输出 CSS。
浏览器支持现状
这是最重要的一个问题。
截至 2026 年中,MDN 明确标注:只有 CSS 自定义函数(@function)有浏览器支持,@mixin 和 @apply 还没有任何浏览器默认支持。
但 Chrome Platform Status 上 @mixin 的状态在 2026 年 7 月悄悄更新了:
- Feature owners:Microsoft(johnjansen、kbabbitt)+ Google(leo.lee)
- Active stage:Prototype(原型实现阶段)
- Chrome Status:No milestones specified(未指定里程碑,但 2026 年是预估发布时间)
- Tracking bug:issues.chromium.org/issues/406935599
Microsoft 是主要推动方,已经在 Chromium 里开始原型实现。如果你在 Chrome 或 Edge,可以手动开启实验开关体验:
chrome://flags/#enable-experimental-web-platform-features
设置为 Enabled,重启浏览器即可。
现在能怎么用
渐进增强策略。
/* Fallback:直接写基础样式 */
.card {
border-radius: 12px;
padding: 1.5rem;
}
/* 支持 @apply 的浏览器会覆盖 */
@supports (selector(&)) {
@mixin --card-enhanced {
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.card {
@apply --card-enhanced;
}
}
@supports (selector(&)) 是目前检测 @mixin 支持的技巧,旧浏览器会跳过整个块,不会报错。
三个实际场景
一,设计系统 token 复用。
@mixin --surface-elevated {
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
}
.sidebar {
@apply --surface-elevated;
}
.modal-overlay {
@apply --surface-elevated;
border-radius: var(--radius-lg);
}
二,响应式工具类。
@mixin --center-flex {
display: flex;
align-items: center;
justify-content: center;
}
.page-loader {
@apply --center-flex;
min-height: 100vh;
}
.button-icon {
@apply --center-flex;
width: 40px;
height: 40px;
}
三,带伪元素的 mixin。
@mixin --arrow-right(--color) {
position: relative;
&::after {
content: "";
position: absolute;
right: -1.5rem;
top: 50%;
transform: translateY(-50%);
border: 6px solid transparent;
border-left-color: var(--color);
}
}
.nav-item-active {
@apply --arrow-right(blue);
}
下一步:要不要迁移
现在不要动。 @mixin 还在 Prototype 阶段,语法可能还有变化,生产项目现在就用是给自己埋坑。
但要开始关注了。 微软在 Chromium 里主推这个 feature,Chrome Status 的 Estimated shipping year 写的是 2026——也就是今年年内。如果你的 Sass 用得比较多,可以提前审视一下哪些 @mixin 可以直接迁移、哪些依赖 Sass 的特有功能需要保留。
记住最重要的一件事: 原生 @mixin 可以写 @media 和 @supports,可以接收 CSS 变量的运行时值,这是 Sass 完全做不到的。即使你已经用了 Sass 五年,这件事的逻辑也彻底变了——不是「把 Sass 搬进浏览器」,是「浏览器里能做 Sass 做不了的事」。
感兴趣可以在 Chrome 开启实验开关试一下:
chrome://flags/#enable-experimental-web-platform-features
不过别在生产项目里用就是了。
评论区
登录后可评论。