← 首页 / CSS 函数 · 值是「算」出来的 待审核 9 页

CSS 函数 · 值是「算」出来的

CSS 属性值远不止 20pxred 这样的字面量 —— 一大票值长成 name(参数) 的样子: calc(100% - 80px)clamp(16px, 4vw, 40px)oklch(0.7 0.15 50)linear-gradient(red, blue)……这种写法叫 functional notation (函数式记法): 函数名 + 括号里的参数, 浏览器拿参数出最终的值。它们不是零散的语法糖, MDN 把全部 value function 归成了 14 类 115 个的一张完整地图。

本系列先用一页全景图认全这 14 类 (用 CSS.supports 实时检测当前浏览器支持哪些); 再深入其中最常用也最新的 math functions: calc()min/max/clamp 的混单位算术、round()/mod()/rem() 的取整策略与负数行为、把任意值线性映射到 0–1 的 progress()、为 CSS 带来原生随机数的 random()、以及 tan(atan2()) —— 用一对三角函数把带单位的长度「类型转换」为纯 number。全程滑块实时重算 + 真实 getComputedStyle 读数。最后把视角反过来: @function at-rule 让你自己定义带参数 / 类型 / 默认值的 CSS 函数。

前置: random() 的「共享语义」涉及 var()文本代换这一机制, 需要时可参考 custom-properties 系列

全景 · 14 类 115 个

函数全景图:你的浏览器认识几个

照 MDN 的分类法把全部 value function 摆成一张地图:transform / math / filter / color / image / counter / shape / reference / grid / font / easing / animation / anchor / tree counting 十四类。每个函数一枚 chip,用 CSS.supports() 实时检测当前浏览器是否支持——绿色支持、红色不支持;点 chip 查看对应的最小探针。换个浏览器打开,这页呈现的结果不同,这正是 Baseline 要解决的问题。

算术与比较 · calc / clamp

calc() 混单位算术与 clamp() 流体值

calc() 的核心能力是混合单位运算: 100% - 80px 在写下时还无法求值,浏览器到 layout 时才代入当下的 100%。再看比较三函数:min() 取最小、max() 取最大、clamp(MIN, 理想值, MAX) 把理想值夹在区间内——流体字号一行即可实现。拖动「视口宽」滑块,在数轴上看 clamp 三个候选值中谁生效、字号如何随之变化。

取整与求余 · round / mod / rem

round() 的四种取整策略,以及 mod 与 rem 的区别

round(策略, 值, 步距) 把值取整到步距的整数倍,四种策略 up / down / nearest / to-zero 恰好对应 JS 的 ceil / floor / round / trunc——差异全在负数上:up 朝 +∞、to-zero 朝零,在数轴上一目了然。再看 mod()rem(): 都是求余,余数的符号取决于谁不同(mod 跟除数、rem 跟被除数,JS 的 % 属于 rem)。附 8px 网格吸附示例与 round(10px, 0) 这类特殊值的实测。

映射 · progress()

progress(): 把任意值线性映射到 0–1

progress(value, start, end) 计算的就是 (value - start) / (end - start),再夹到 [0, 1]——一个标准的归一化函数。得到 0–1 的数后,乘以什么就插值什么:透明度、色相、圆角。重点在它接受 length: progress(100vw, 320px, 1200px) 这种「长度除长度」用 calc 写不出来(单位约不掉), progress() 内部负责约分。附在所有浏览器都能运行的等价写法与实测对照。

随机 · random()

random(): CSS 原生掷骰子

random(min, max, step?) 为 CSS 带来原生随机数——绘制一片星空无需任何 JS。最需要厘清的是「随机值由谁共享」: 默认每处使用各自取值;--ident 让同一元素内多个属性共用同一个值(用 var() 存储无效,因为 var 是文本代换、每处代换各取一次); element-shared 让所有元素共享;两者叠加 = 全局一份。2×2 矩阵把四种语义并列对照,星空 demo 在支持的浏览器使用真实 CSS、否则用 JS 模拟并明确标注。

类型转换 · tan(atan2())

tan(atan2()): 把长度转换成 number

calc() 不允许「长度除长度」,但 atan2(A, B) 接受两个同量纲的值、内部只取比值——单位随即约掉;tan() 再把角还原成比值:tan(atan2(A, B)) = A / B,一对三角函数充当单位消除器。三个示例全程零 JS: 100vw 读成数字(@property 先定形成 px)、容器宽折合多少 em、12s 换算成 12001ms——数字由 counter() 打印。末尾把混单位 / 裸写不包 calc / 除数为 0 / 大比值精度等历史问题列成一张表,实时检测你的浏览器表现。

相对色 · alpha()

alpha(): 只改透明度的颜色函数

alpha(from <color> / 值) 吃一个 origin color, 三个色度通道原样保留,只把透明度替换缩放——它是 relative color 语法 (rgb(from c r g b / alpha)) 的单通道便捷形式,不必把 r g b 整套抄一遍。斜杠后既能给常量(/ 80% 直接覆盖),也能借 alpha 关键字(origin 透明度的 <number>)进 calc: calc(alpha * .25) = 在原透明度上再打到四分之一。出自 CSS Color 5(草案),支持 alpha() 的浏览器跑真函数、其余自动退回等价的 relative color 展开形式并标注。

自定义函数 · @function

@function: 定义你自己的 CSS 函数

前面几页讲的都是浏览器内置的函数——只能用、不能造。@function at-rule 反过来:author 自己定义带参数<length> / <color>类型约束默认值returns 返回类型的可复用函数,内部还能写局部变量和逻辑,用 result 吐值。它不是 var() 那种文本代换,而是真正的求值。两个 demo(调浅颜色的 --tint、封装流体字号的 --fluid)在 Chromium 139+ 跑真 @function,其余浏览器退回 JS 模拟并标注。

链接参数 · param()

param(): 把 CSS 变量传进被引用的图片里

其余函数都是「把输入成一个值」,param() 是个例外:它不计算,而是在引用一张图片的地方<img> 的 URL 片段、link-parameters 属性、或 url() 内)往那张图塞进一个具名参数;图片内部(通常是 SVG)再用 env(--x, fallback) 把它接出来。解决的痛点是 <img> / background-image 引入的外部 SVG 是隔离沙箱,外层 var() / currentColor 进不去——param() 给这道墙开一扇单向具名传参口,一份资源即可随调用方换色。出自 CSS Linked Parameters 草案,尚无浏览器实现,全程 JS 模拟 env() 代换并标注。

🔗 相关链接

📐 规范 / 文档

各页的主要来源放在对应子页末尾的「相关链接」里。下面是贯穿全系列的总参考: