配了八年 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

不过别在生产项目里用就是了。

评论区

0 条评论

登录后可评论。