写了八年 Sass,每次想复用一段值逻辑都要靠变量硬凑——今天 CSS 自己会了
你一定见过这种代码:Sass 里写一个 $base-color 变量,然后一堆 $primary-dark、$primary-darker、$primary-darkest,全靠手算百分比拼出来。每次加一个新颜色都要复制粘贴一整列。
这事今天被 Chrome 139 里一个叫 @function 的 CSS 规范彻底原生化了——不再需要预处理器,不再需要构建步骤,浏览器自己算。
它是什么
CSS @function 让你在样式表里直接定义带参数、可复用、有逻辑的值函数。语法长这样:
@function --generate-shade(--base-color, --percentage) {
result: color-mix(in srgb, var(--base-color), black var(--percentage));
}
.themed {
--primary-color: #3b82f6;
--primary-color-dark: --generate-shade(var(--primary-color), 20%);
}
@function 定义函数,result 描述符返回计算结果,调用时用 –function-name() 语法——和普通 CSS 自定义属性几乎一样,只是多了括号和参数。
和 Sass/Less 什么关系
先别急着喊「Sass 死了」。@function 目前只处理值,不处理声明块。它替代的是 Sass 里的函数(不是 @mixin),比如这样:
// Sass 函数
@function generate-shade($color, $percent) {
@return mix(black, $color, $percent);
}
.button { background: generate-shade($primary, 20%); }
对应 CSS 原生写法:
@function --generate-shade(--color, --percent) {
result: color-mix(in srgb, var(--color), black calc(var(--percent) * 1%));
}
.button { background: --generate-shade(var(--primary), 20); }
构建步骤没了,但参数传递、逻辑计算、颜色混算这些能力都在。
那 @mixin 呢?那个用 @apply 应用的规范目前没有任何浏览器支持,连 Chrome 实验都没开。Sass 的 @mixin 体系暂时还动不了。
实战场景
场景一:色值派生
不用再写一整列 darken/lighten 变量了:
@function --shade(--color, --pct) {
result: color-mix(in srgb, var(--color), black var(--pct));
}
@function --tint(--color, --pct) {
result: color-mix(in srgb, var(--color), white var(--pct));
}
:root { --brand: #3b82f6; }
.card { background: var(--brand); }
.card-dark { background: --shade(var(--brand), 20%); }
.card-light { background: --tint(var(--brand), 80%); }
场景二:流体间距
不再需要 clamp 硬写:
@function --fluid-space(--min, --max, --viewport-min: 320, --viewport-max: 1200) {
result: clamp(var(--min), calc(var(--min) + (var(--max) - var(--min)) * ((100vw - var(--viewport-min) * 1px) / (var(--viewport-max) - var(--viewport-min)))), var(--max));
}
.section { padding: --fluid-space(16px, 48px); }
场景三:带默认值的参数
默认参数规范还没广泛支持,用函数体内 var() 兜底:
@function --scale(--size) {
--safe: var(--size, 1rem);
result: calc(var(--safe) * 1.5);
}
.box-1 { width: --scale(); /* 1.5rem */ }
.box-2 { width: --scale(2rem); /* 3rem */ }
浏览器支持
- Chrome 139+ ✅(2025年8月稳定发布)
- Edge 139+ ✅
- Opera 123+ ✅
- Firefox ❌
- Safari ❌
- 全球覆盖率:约 73%(Chrome + Edge + Opera 桌面版合计)
三个坑:
坑一:只有值,没有声明块。 很多文章说「Sass 末日到了」,实际上 @mixin/@apply 根本还没进任何浏览器。能用的是 @function,只处理值层面,别期待太高。
坑二:默认参数。 参数表里的默认值语法(–size: 1rem)还没广泛实现,用函数体内的 –safe: var(–size, 1rem) 代替。
坑三:渐进增强必须做。 老浏览器不认识 @function,需要先写兜底值:
.element {
--border-color: #cc0000; /* 兜底,老浏览器用这个 */
--border-color: --generate-shade(crimson, 10%); /* 新浏览器覆盖 */
}
三步下一步
- 打开 Chrome 139+ 试跑 — 在 DevTools Elements 面板里直接写一个 @function 测试,–transparent(color, alpha) 那种
- 改造一个 Sass 函数 — 选项目里用 @function 或运算拼出来的色值/间距工具,改成 CSS @function,保留 Sass 作为 fallback
- 加 @supports 渐进增强 — 用
@supports (background: --generate-shade(red, 20%))做显式特性检测,比级联兜底更安全
CSS 正在一点点吃掉预处理器最核心的能力。@function 只是开始,@mixin/@apply 还在规范讨论里。等 Safari 和 Firefox 也跟上来,Sass 的工具函数层可能真的要重新评估了。
评论区
登录后可评论。