calc() 混单位算术与 clamp() 流体值
calc() 的关键能力不是「能算术」——是混合单位运算。width: calc(100% - 80px) 在写下的那一刻无法求值:100% 等于多少要到 layout 时才确定。浏览器把这个表达式原样带到布局阶段,代入当下的容器宽再得出结果——容器变化时,结果随之变化。这是预处理器
(Sass) 在构建期固定下来的数字无法做到的。
1 · calc(): 100% 是多少,到 layout 才揭晓
一个常见语法陷阱: + - 两侧必须留空格。calc(100% -80px) 不是减法——-80px 会被解析为一个负值 token,整条声明非法。乘除 * / 不强制空格,但除数必须是无单位数:
calc(100px / 2) 合法,calc(100px / 2px) 不合法 (「长度除长度」的需求由 progress() 接手)。另有新成员 calc-size(auto, size),专为「向 auto 做动画」这一长期难题而设计。
2 · min / max / clamp: 把值夹进区间
min() 取参数里最小的、max() 取最大的——名字说的是结果,用途常常反着读:width: min(100%, 600px) 读作「最宽不超过 600px」。clamp(MIN, 理想值, MAX) 则是三明治:理想值在区间内就用它,越界就被夹住,等价于
max(MIN, min(理想值, MAX))。最常见的用法是流体字号: 理想值挂在视口宽上,两端再钉死下限和上限。
小结: calc() 把求值推迟到浏览器知道结果的那一刻;clamp() 为可变的值设定两端边界。真实项目中理想值通常写成 1rem + 2vw 这种带 rem 的混合式——纯 vw 的字号在用户使用浏览器缩放时也放不大,是无障碍方面的明显缺陷。