函数
CSS 数值函数完整原理:calc/min/max/clamp 的语法、单位混合规则、嵌套与响应式应用。
前置知识
建议先阅读以下内容再进入本文:
1. 历史动机与发展脉络
CSS 早期没有计算能力,布局中“容器宽度减去固定侧栏”只能依赖百分比近似或 JS 计算。CSS Values and Units Level 3 于 2011 年前后开始定义 calc(),2013 年后主流浏览器陆续支持。min()/max()/clamp() 属于 CSS Values and Units Level 4,2020 年前后获得主流支持,补齐了“取极值”与“钳制”能力。
颜色函数的发展同样显著:rgba()/hsla() 在 CSS3 Color 中标准化(2011);CSS Color 4(2023 年成为候选推荐)引入 color-mix()、oklch()、lab() 等现代色彩空间函数,使颜色混合与感知均匀性成为可能。渐变函数从 CSS3 的 linear-gradient 演进到支持角度、位置、重复渐变与锥形渐变。
CSS 变量(自定义属性)在 CSS Custom Properties for Cascading Variables Level 1(2012 年草案,2015 年后广泛支持)中定义,var() 成为主题系统的基石,并与数学函数形成组合:calc(var(--gap) * 2)。
timeline
title CSS 函数演进
2011 : calc() 进入 CSS Values 3
2013 : 主流浏览器支持 calc()
2015 : CSS 变量 var() 广泛支持
2020 : min/max/clamp 主流支持
2023 : CSS Color 4 color-mix 可用
2025 : oklch 成为现代色彩工作流标配
2. 形式化定义
2.1 数学函数
calc(表达式):对长度、百分比、角度、时间等数值类型执行加减乘除。语法约束:+ 与 - 两侧必须有空格(避免与正负号歧义),* 与 / 不需要空格但两侧操作数类型受限(乘法至少一侧为数字,除法右侧必须为数字且不能为零)。
min(值1, 值2, ...):返回参数中的最小值,参数可以混合单位,但最终结果类型必须一致。
max(值1, 值2, ...):返回最大值。
clamp(最小值, 首选值, 最大值):等价于 max(最小值, min(首选值, 最大值))。首选值被钳制在区间内。
现代 CSS 还提供了完整的数值函数族(2024-2026 逐步进入基线):
sin(角度)、cos(角度)、tan(角度):三角函数,角度用 deg/rad/turn 表示,常用于周期性动画与圆形轨迹计算。
asin(x)、acos(x)、atan(x)、atan2(y, x):反三角函数,atan2 接收两个参数,用于从坐标反推角度(如指针旋转)。
exp(x)、log(x)、sqrt(x)、pow(x, y)、hypot(a, b):指数与根式函数,适合缩放曲线与物理模拟。
abs(x)、sign(x):绝对值与符号函数。
round(x)、mod(a, b)、rem(a, b):取整与余数函数,round() 可指定策略(nearest/up/down)。
/* 示例:用三角函数做圆形轨道上的装饰点 */
.orbit {
left: calc(50% + 120px * cos(45deg));
top: calc(50% + 120px * sin(45deg));
}
讲解: 多数项目日常只用 calc()/clamp();三角函数与指数函数适合图形、图表、动画类场景,使用前用 @supports 做能力检测。
2.2 变量函数
var(--name, 回退值):读取自定义属性 --name 的值;若未定义或无效,使用回退值。回退值本身可以使用其他函数(如 var(--x, calc(...)))。
自定义属性的特性:值在声明处不校验类型,只有在被使用处的属性上下文中才校验;继承性使变量可以从 :root 传播到所有元素;@property 可以注册带类型与初始值的自定义属性,支持动画。
2.3 颜色函数
rgb(r g b / a) 与 rgba(r g b / a):红绿蓝三通道加透明度;现代语法允许空格分隔与斜杠透明度,也支持逗号旧语法。
hsl(h s l / a):色相(角度或数字)、饱和度、亮度;oklch(l c h / a) 是感知均匀的色彩空间。
color-mix(in srgb, 颜色1 40%, 颜色2):按比例混合两种颜色,in 指定混合色彩空间。
2.4 渐变函数
linear-gradient(方向, 色标...)、radial-gradient(形状 尺寸 at 位置, 色标...)、conic-gradient(from 角度 at 位置, 色标...);repeating- 前缀生成重复渐变。
flowchart TD
A["CSS 函数"] --> B["数学:calc/min/max/clamp"]
A --> C["变量:var()"]
A --> D["颜色:rgb/hsl/oklch/color-mix"]
A --> E["渐变:linear/radial/conic"]
B --> F["布局尺寸计算"]
C --> G["主题与设计令牌"]
D --> H["主题色派生"]
E --> I["装饰与视觉层次"]
3. 理论推导与原理解析
3.1 计算值求值时机
CSS 属性值经历指定值、计算值、使用值、实际值四个阶段。数学函数在“计算值”阶段完成求值,此时单位类型已经统一(长度转换为像素或视口单位),因此 calc(100% - 40px) 最终得到确定长度。理解求值时机可以解释:min()/max() 中混合百分比与固定值不会产生无限递归,因为百分比在布局阶段解析。
3.2 var() 的替换规则
var() 在自定义属性解析阶段替换,替换后整个声明重新参与计算。若替换结果对当前属性无效,该声明变为“无效 at 计算值时间”(invalid at computed-value time),此时使用属性的初始值或继承值,而不是回退值——这是 var() 与普通属性最大的行为差异。因此回退值只在变量本身未定义时生效。
3.3 clamp 的流体推导
流体排版的数学表达:字号 = clamp(最小字号, 视口相关值, 最大字号)。视口相关值常用 vw 单位,例如 clamp(1rem, 1rem + 1vw, 1.5rem)。推导:视口宽度为 0 时取 1rem,视口为 100vw 时约 2rem,但被钳制在 1.5rem。该公式让字号在区间内线性变化,避免媒体查询逐断点跳变。
3.4 color-mix 的混合模型
color-mix(in srgb, red 40%, blue) 在指定色彩空间插值。比例表示第一种颜色的权重,未指定权重时按 50/50 混合。混合空间的感知均匀性影响结果:oklab 混合比 srgb 混合更接近人眼感知的中途色。
4. 代码示例(带详尽注释)
4.1 calc() 基础
/* 侧栏固定 240px,主区域占满剩余空间 */
.main {
width: calc(100% - 240px);
margin-left: 240px;
}
/* 运算符两侧必须有空格 */
.header {
padding: calc(1rem + 2px) calc(2rem - 4px);
}
讲解:calc(100% - 240px) 是经典布局公式。注意 +/- 两侧空格是语法要求,缺少空格整个声明无效。
4.2 min() 与 max()
/* 内容宽度最大 1200px,小屏时占满可用空间(减去两侧内边距) */
.container {
width: min(1200px, 100% - 32px);
margin-inline: auto;
}
/* 按钮最小宽度 160px,但不超过容器 100% */
.button {
width: max(160px, 100%);
}
讲解:min() 表达“上界”,max() 表达“下界”。width: min(1200px, 100% - 32px) 取代了 max-width + width 的旧写法,语义更直接。
4.3 clamp() 流体排版
/* 标题字号:最小 1.5rem,视口相关增长,最大 3rem */
.hero-title {
font-size: clamp(1.5rem, 1rem + 2.5vw, 3rem);
}
/* 间距也流体化 */
.section {
padding-block: clamp(2rem, 1rem + 4vw, 6rem);
}
讲解:clamp() 让字号随视口连续变化,兼顾小屏可读性与大屏视觉冲击。vw 系数决定增长斜率,可通过设计稿两端值反推。
4.4 var() 与主题系统
:root {
--color-primary: #1677ff;
--space-md: 16px;
--radius: 8px;
}
.card {
/* 变量参与计算 */
padding: var(--space-md);
border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent);
border-radius: var(--radius);
}
/* 深色主题只需覆盖变量 */
@media (prefers-color-scheme: dark) {
:root {
--color-primary: #4096ff;
}
}
讲解:var() 与 color-mix() 组合:边框颜色自动从主题色派生。主题切换只改变量定义,组件样式零改动。
4.5 color-mix() 派生色
.button {
background: var(--color-primary);
}
/* 悬停色:主色与黑色混合 10% */
.button:hover {
background: color-mix(in srgb, var(--color-primary) 90%, black);
}
/* 禁用态:主色 40% 透明 */
.button:disabled {
background: color-mix(in srgb, var(--color-primary) 40%, transparent);
}
讲解:color-mix 取代了手写调色板。主色改变时,悬停、禁用、边框等派生色自动跟随,是设计系统维护的利器。
4.6 渐变函数
/* 线性渐变:135 度方向,三段色标 */
.hero {
background: linear-gradient(135deg, #1677ff 0%, #69b1ff 50%, #d3e7ff 100%);
}
/* 径向渐变:从左上角扩散 */
.sun {
background: radial-gradient(circle at 30% 30%, #fff7d6, #ffc53d);
}
/* 锥形渐变:从 0 度开始,用于环形图 */
.pie {
background: conic-gradient(from 0deg, #1677ff 0% 40%, #52c41a 40% 70%, #faad14 70% 100%);
}
讲解:三种渐变覆盖主流场景:线性用于横幅与按钮,径向用于光晕,锥形用于环形图。渐变函数之间可以叠加(多层 background),创造丰富层次。
4.7 渐变与 mask 组合
/* 淡出遮罩:内容底部渐隐 */
.fade-bottom {
-webkit-mask-image: linear-gradient(to bottom, black 60%, transparent);
mask-image: linear-gradient(to bottom, black 60%, transparent);
}
讲解:mask-image 用亮度控制透明度,黑色区域显示、透明区域隐藏。该技巧常用于长文本折叠预览。
4.8 @supports 回退
/* 支持 clamp 的浏览器使用流体字号 */
.title {
font-size: 1.5rem;
}
@supports (font-size: clamp(1rem, 2vw, 3rem)) {
.title {
font-size: clamp(1.5rem, 1rem + 2vw, 3rem);
}
}
讲解:@supports 做特性检测,旧浏览器获得回退值。现代项目只需对极少数新函数(如 color-mix 早期版本)做此类保护。
5. 对比分析
5.1 原生函数与 Sass 函数
| 维度 | 原生 CSS 函数 | Sass 函数 |
|---|---|---|
| 求值时机 | 浏览器运行时 | 构建时 |
| 动态性 | 随视口/变量变化 | 静态结果 |
| 变量 | var() 运行时替换 | 编译期替换 |
| 依赖 | 无 | 构建工具链 |
5.2 min/max/clamp 与媒体查询
clamp() 的流体方案在断点之间连续过渡,媒体查询是分段跳变。两者可结合:流体负责区间内,媒体查询负责结构性布局变化(单列到多列)。
5.3 calc 与容器查询
calc() 解决尺寸计算,容器查询解决组件级响应。例如卡片内部间距用 calc(),卡片网格列数用容器查询,各司其职。
6. 常见陷阱与最佳实践
陷阱一:calc() 的 +/- 忘记空格。声明静默无效。
陷阱二:var() 回退值只在变量未定义时生效;变量存在但值无效时回退值不会兜底。
陷阱三:在 min()/max() 中混入无单位数字与长度。min(1, 100px) 类型不匹配,整个声明无效。
陷阱四:clamp() 中最小值大于最大值。结果是不可预测的,浏览器按规范处理仍可能异常。
陷阱五:color-mix 早期浏览器前缀与语法差异。现代浏览器无前缀支持,使用前可用 @supports 检测。
陷阱六:渐变中色标位置不递增导致硬边。按顺序递增色标位置,或用 hsl 表达连续色相变化。
最佳实践:数学函数优先于魔法数字;主题色统一走 var() + color-mix();流体排版用 clamp() 并保留回退;渐变用于装饰而非关键信息。
7. 工程实践
7.1 间距与排版令牌
:root {
--space-1: 4px;
--space-2: 8px;
--space-3: 16px;
--space-4: 24px;
--space-5: 32px;
--text-base: clamp(1rem, 0.95rem + 0.2vw, 1.125rem);
}
讲解:间距按 4px 基准递增,排版用 clamp 流体化。令牌化让设计与代码共享同一套词汇。
7.2 布局网格中的函数
/* auto-fill 自动列数 + min() 控制列宽下界 */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
gap: clamp(12px, 2vw, 24px);
}
讲解:minmax(min(240px, 100%), 1fr) 防止窄容器中 240px 溢出,auto-fill 自动计算列数。这是 CSS 网格与函数组合的经典响应式配方。
8. 案例研究:无 JS 的主题化卡片系统
需求:一套卡片组件,支持浅深色主题、派生悬停色、流体间距与圆角,全部由 CSS 函数与变量实现。
:root {
/* 主题令牌 */
--color-primary: #1677ff;
--color-surface: #ffffff;
--color-text: #1f1f1f;
--radius-card: 12px;
--space-card: clamp(12px, 2vw, 24px);
}
/* 深色主题仅覆盖表面色与文字色 */
@media (prefers-color-scheme: dark) {
:root {
--color-surface: #1f1f1f;
--color-text: #e8e8e8;
}
}
.card {
background: var(--color-surface);
color: var(--color-text);
border: 1px solid color-mix(in srgb, var(--color-text) 15%, transparent);
border-radius: var(--radius-card);
padding: var(--space-card);
transition: transform 0.2s ease;
}
.card:hover {
transform: translateY(-2px);
border-color: color-mix(in srgb, var(--color-primary) 40%, transparent);
}
/* 标题字号流体 */
.card h3 {
font-size: clamp(1.1rem, 1rem + 0.5vw, 1.4rem);
}
讲解:整个系统不依赖任何 JS:主题切换由媒体查询驱动,派生色由 color-mix 计算,间距与字号由 clamp 流体化。新增组件只需引用令牌,天然获得主题一致性。
9. 知识要点总结与深入讲解
CSS 函数让样式表具备计算能力:calc() 做差值,min/max 做边界,clamp 做区间钳制。三者都以“计算值”阶段的类型安全为前提,因此混合单位是它们的核心价值。
var() 是主题系统的支柱,其行为特殊性(无效值不回退)要求开发者理解“变量存在但值无效”与“变量未定义”的区别。@property 进一步把变量升级为带类型的注册属性,支持动画与校验。
颜色函数的演进方向是感知均匀与可计算:oklch 让色相旋转更自然,color-mix 让派生色自动化。设计系统的维护成本因此大幅下降。
1. calc() 函数
.element {
width: calc(100% - 60px);
}
.element {
height: calc(50vh - 2rem);
}
.element {
font-size: calc(16px + 0.5vw);
}
规则:可以混合不同单位;运算符前后必须有空格;可以嵌套。
1. min() 函数
.element {
width: min(50vw, 400px);
} /* 取较小值 */
2. max() 函数
.element {
width: max(50vw, 300px);
} /* 取较大值 */
3. clamp() 函数
h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
}
等价于:
h1 {
font-size: 1.5rem;
font-size: max(1.5rem, min(5vw, 3rem));
}
4. 其他 CSS 函数
.element {
width: var(--width, 100%); /* 自定义属性 */
transform: translateX(50px); /* 变换 */
filter: blur(5px); /* 滤镜 */
color: color-mix(in srgb, red 50%, blue); /* 颜色混合 */
}
calc() 计算
基本写法:calc 基本运算
calc(<值1> <运算符> <值2>);
/* 加减乘除运算 */
.box {
width: calc(100% - 200px);
height: calc(50vh + 50px);
padding: calc(20px * 2);
}
基本写法:calc 混合单位
calc(<单位1> <运算符> <单位2>);
/* 混合不同单位计算 */
.box {
font-size: calc(1rem + 0.5vw);
margin: calc(20px - 1em);
}
基本写法:calc 嵌套
calc(<值> * calc(<值>));
/* calc 嵌套使用 */
.box {
width: calc(100% - calc(200px + 2rem));
}
基本写法:calc 配合变量
calc(var(--<变量>) <运算符> <值>);
/* 变量参与计算 */
.box {
--base: 20px;
padding: calc(var(--base) * 2);
}
基本写法:calc 运算优先级
calc((<值1> + <值2>) * <值3>);
/* 括号控制运算优先级 */
.box {
width: calc((100% - 40px) / 3);
}
min() 取最小值
基本写法:min 取最小
min(<值1>, <值2>[, ...]);
/* 取多个值中最小者 */
.box {
width: min(50%, 300px);
}
基本写法:min 混合单位
min(<单位1>, <单位2>);
/* 混合单位取最小 */
.text {
font-size: min(5vw, 1.5rem);
}
基本写法:min 多值
min(<值1>, <值2>, <值3>);
/* 多个值取最小 */
.box {
width: min(100%, 800px, 90vw);
}
max() 取最大值
基本写法:max 取最大
max(<值1>, <值2>[, ...]);
/* 取多个值中最大者 */
.box {
width: max(50%, 300px);
}
基本写法:max 混合单位
max(<单位1>, <单位2>);
/* 字体不小于 16px */
.text {
font-size: max(1rem, 16px);
}
基本写法:max 多值
max(<值1>, <值2>, <值3>);
/* 多个值取最大 */
.box {
min-height: max(100px, 10vh, 5rem);
}
clamp() 钳制
基本写法:clamp 钳制范围
clamp(<最小>, <理想>, <最大>);
/* 值在 1rem 到 3rem 之间理想 2vw+1rem */
h1 {
font-size: clamp(1rem, 2vw + 1rem, 3rem);
}
基本写法:clamp 响应式字体
clamp(<最小rem>, <理想vw>, <最大rem>);
/* 流式响应字体 */
p {
font-size: clamp(1rem, 2.5vw, 1.5rem);
}
基本写法:clamp 响应式间距
clamp(<最小>, <理想>, <最大>);
/* 流式响应间距 */
.section {
padding: clamp(1rem, 4vw, 3rem);
}
基本写法:clamp 响应式宽度
clamp(<最小>, <理想>, <最大>);
/* 容器最大宽度限制 */
.container {
width: clamp(320px, 90vw, 1200px);
margin: 0 auto;
}
基本写法:clamp 等价 max min
max(<最小>, min(<理想>, <最大>));
/* clamp 等价写法 */
h1 {
font-size: max(1rem, min(2vw + 1rem, 3rem));
}
var() 变量引用
基本写法:var 引用变量
var(--<属性名>);
/* 引用自定义属性 */
.box {
color: var(--primary-color);
}
基本写法:var 带默认值
var(--<属性名>, <默认值>);
/* 变量未定义时使用默认值 */
.box {
color: var(--text-color, #333);
}
颜色函数
基本写法:rgb rgba 颜色
rgba(<r>, <g>, <b>, <alpha>);
/* RGBA 颜色带透明度 */
.box {
background: rgba(52, 152, 219, 0.5);
}
基本写法:hsl hsla 颜色
hsla(<色相>, <饱和度>, <亮度>, <alpha>);
/* HSLA 颜色 */
.box {
background: hsla(210, 70%, 50%, 0.5);
}
基本写法:现代 rgb 空格语法
rgb(<r> <g> <b> / <alpha>);
/* 现代空格分隔语法 */
.box {
background: rgb(52 152 219 / 50%);
}
基本写法:十六进制带透明度
#RRGGBBAA;
/* 8 位十六进制带透明度 */
.box {
background: #3498db80;
}
基本写法:color-mix 混合颜色
color-mix(in <色彩空间>, <颜色1> <比例>, <颜色2>);
/* 混合两种颜色 */
.box {
background: color-mix(in srgb, #3498db 50%, white);
}
基本写法:color-mix 基于 oklch
color-mix(in oklch, <颜色1> <比例>, <颜色2>);
/* OKLCH 色彩空间混合更准确 */
.box {
background: color-mix(in oklch, var(--primary) 70%, black);
}
基本写法:light-dark 明暗切换
light-dark(<浅色>, <深色>);
/* 自动明暗模式颜色 */
.text {
color: light-dark(#333, #fff);
}
基本写法:oklch 感知亮度颜色
oklch(<亮度> <色度> <色相>);
/* OKLCH 色彩空间 */
.box {
background: oklch(60% 0.2 240);
}
基本写法:相对颜色
oklch(from <基础色> <亮度> <色度> <色相>);
/* 基于现有颜色派生新颜色 */
.darker {
background: oklch(from var(--primary) calc(l - 0.1) c h);
}
渐变函数
基本写法:linear-gradient 线性渐变
linear-gradient(<角度>, <颜色1>, <颜色2>);
/* 线性渐变背景 */
.box {
background: linear-gradient(45deg, #3498db, #2ecc71);
}
基本写法:radial-gradient 径向渐变
radial-gradient(<形状>, <颜色1>, <颜色2>);
/* 径向渐变 */
.box {
background: radial-gradient(circle, #3498db, #2c3e50);
}
基本写法:conic-gradient 锥形渐变
conic-gradient(from <角度>, <颜色1>, <颜色2>);
/* 锥形渐变 */
.box {
background: conic-gradient(from 0deg, red, yellow, green, red);
}
基本写法:渐变停顿点
linear-gradient(<角度>, <颜色> <位置>, <颜色> <位置>);
/* 控制渐变停顿位置 */
.box {
background: linear-gradient(to right, #3498db 0%, #2ecc71 50%, #f1c40f 100%);
}
形状与路径函数
基本写法:path 路径
path("<SVG路径>");
/* 沿 SVG 路径运动 */
.element {
offset-path: path("M 0 0 L 100 100");
animation: move 3s;
}
基本写法:clip-path 裁剪
clip-path: <形状函数>;
/* 圆形裁剪 */
.avatar {
clip-path: circle(50%);
}
基本写法:clip-path 多边形
clip-path: polygon(<点1>, <点2>, ...);
/* 三角形裁剪 */
.triangle {
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
基本写法:clip-path inset
clip-path: inset(<上> <右> <下> <左> round <圆角>);
/* 矩形裁剪带圆角 */
.box {
clip-path: inset(10% 10% 10% 10% round 20px);
}
滤镜函数
基本写法:blur 模糊
filter: blur(<半径>);
/* 高斯模糊 */
.glass {
filter: blur(5px);
}
基本写法:brightness 亮度
filter: brightness(<比例>);
/* 提亮 1.5 倍 */
.image {
filter: brightness(1.5);
}
基本写法:contrast 对比度
filter: contrast(<比例>);
/* 提高对比度 */
.image {
filter: contrast(1.2);
}
基本写法:grayscale 灰度
filter: grayscale(<比例>);
/* 完全灰度 */
.image {
filter: grayscale(1);
}
基本写法:组合滤镜
filter: <滤镜1> <滤镜2>;
/* 多个滤镜组合 */
.image {
filter: brightness(1.1) contrast(1.2) saturate(1.5);
}
数学函数组合
基本写法:clamp 配合 calc
clamp(<最小>, calc(<表达式>), <最大>);
/* clamp 内嵌 calc */
.box {
width: clamp(200px, calc(50vw - 100px), 800px);
}
基本写法:min 配合 max
min(<值>, max(<值>, <值>));
/* min max 嵌套 */
.box {
width: min(90vw, max(300px, 50vw));
}
基本写法:calc 配合 min/max
calc(min(<值1>, <值2>) + <值>);
/* 复杂函数组合 */
.box {
padding: calc(min(5vw, 30px) + 10px);
}
实用模式
基本写法:响应式排版比例
clamp(<最小rem>, calc(<系数>vw + <基础rem>), <最大rem>);
/* 标准流式字体公式 */
h1 { font-size: clamp(2rem, calc(2.5vw + 1rem), 3.5rem); }
h2 { font-size: clamp(1.5rem, calc(2vw + 0.5rem), 2.5rem); }
p { font-size: clamp(1rem, calc(0.5vw + 0.9rem), 1.25rem); }
基本写法:响应式容器
width: min(<值1>, <值2>); margin: 0 auto;
/* 自适应容器最大宽度 */
.container {
width: min(90vw, 1200px);
margin-inline: auto;
}
基本写法:动态间距
gap: clamp(<最小>, <理想>, <最大>);
/* 流式响应间距 */
.grid {
display: grid;
gap: clamp(0.5rem, 2vw, 2rem);
}
基本写法:基于视口的高度
height: calc(100vh - <偏移>);
/* 全屏减去导航高度 */
.main {
height: calc(100vh - 60px);
}
其他函数
基本写法:env 环境变量
env(<变量名>, <默认值>);
/* 安全区适配刘海屏 */
.app {
padding-top: env(safe-area-inset-top, 0);
padding-bottom: env(safe-area-inset-bottom, 0);
}
基本写法:attr 属性值(增强版)
attr(<属性名> <类型>, <默认值>);
/* 从 HTML 属性读取值(2024+ 类型化 attr) */
.tooltip {
--pos: attr(data-position);
/* 实验性:attr(data-size px, 16px); */
}
基本写法:counter 计数器
counter(<名称>);
/* 自动编号 */
h2::before {
content: counter(chapter) ". ";
}
基本写法:counter 嵌套
counters(<名称>, "<分隔符>");
/* 多级编号 */
li::before {
content: counters(section, ".") " ";
}
动手试试
- 用
calc()计算“100% 减去固定间距”的宽度; - 用
clamp()让标题字号随视口平滑变化; - 用
min()/max()实现自适应尺寸; - 进阶挑战:用
var()组合多个设计令牌。
核心知识点
一句话记住函数:
calc()算数值,clamp()定范围,min()/max()取极值,var()读变量,attr()取属性。
calc():混合单位运算,如calc(100% - 2rem);clamp(min, 首选, max):响应式字号首选;min()/max():多值取最小/最大;var():读取 CSS 变量,支持回退值var(--x, 默认);attr():读取 HTML 属性生成内容;- 颜色函数:
rgb()/hsl()/color-mix()。
注意事项与改进建议
| 问题点 | 说明 | 改进方案 |
|---|---|---|
| calc 空格错误 | 表达式失效 | +/- 两侧必须有空格 |
| 嵌套过深 | 可读性差 | 拆成变量 |
| 滥用 min/max | 行为难预测 | 明确语义场景 |
| var 拼错名 | 回退到默认 | 定义处与使用处保持一致 |
扩展学习
- 变量:
css/410-CSSVariableCustomAttribute; - 颜色:
css/400-ModernColorSpace; - 响应式:
css/370-ResponsiveDesign。