Functions in CSS?! 原来 CSS 也能这么强大
CSS 早已不是简单的样式声明语言。随着现代 CSS 的发展,函数式编程的思想已经深入 CSS 的各个角落。从计算函数到颜色函数,从自定义属性到即将到来的 @function 规则,CSS 正在变得越来越强大。
CSS 函数概览
CSS 函数是一种特殊的值类型,它接受参数并返回计算后的结果。现代 CSS 已经拥有超过 50 个内置函数:
css/* CSS 函数的基本形式 */ property: function-name(argument1, argument2, ...); /* 函数可以嵌套使用 */ property: outer-function(inner-function(value));
函数分类速览
| 类别 | 函数 | 用途 |
|---|---|---|
| 数学函数 | calc(), min(), max(), clamp() | 动态计算值 |
| 颜色函数 | rgb(), hsl(), oklch(), color-mix() | 颜色定义与混合 |
| 图形函数 | linear-gradient(), radial-gradient() | 渐变背景 |
| 变换函数 | translate(), rotate(), scale() | 元素变换 |
| 滤镜函数 | blur(), brightness(), contrast() | 视觉效果 |
| 形状函数 | circle(), polygon(), path() | 裁剪路径 |
| 引用函数 | var(), attr(), url() | 值引用 |
数学函数:动态计算的基石
calc() - 万能计算器
calc() 是 CSS 中最常用的函数,支持混合单位计算:
css.container { /* 混合单位计算 */ width: calc(100% - 2rem); /* 嵌套计算 */ padding: calc(var(--base-spacing) * 2); /* 复杂表达式 */ margin-top: calc((100vh - var(--header-height)) / 2); } /* 响应式字体大小 */ .fluid-text { /* 基础大小 + 视口相关增量 */ font-size: calc(1rem + 0.5vw); } /* 网格布局计算 */ .grid-item { /* 考虑间距的列宽 */ width: calc((100% - 3 * var(--gap)) / 4); }
min() 和 max() - 响应式边界
css.responsive-container { /* 最大不超过 1200px,最小不小于内容宽度 */ width: min(100% - 2rem, 1200px); /* 确保最小可读性 */ font-size: max(16px, 1vw); /* 嵌套使用 */ padding: min(max(1rem, 3vw), 3rem); } /* 响应式间距 */ .section { padding-block: min(10vh, 100px); gap: max(1rem, 2vw); }
clamp() - 一函数搞定响应式
clamp(min, preferred, max) 是响应式设计的利器:
css/* 流体排版系统 */ :root { /* 标题:24px - 5vw - 48px */ --heading-1: clamp(1.5rem, 4vw + 1rem, 3rem); --heading-2: clamp(1.25rem, 3vw + 0.5rem, 2.25rem); --heading-3: clamp(1.125rem, 2vw + 0.5rem, 1.75rem); /* 正文 */ --body-text: clamp(1rem, 1vw + 0.75rem, 1.25rem); /* 间距 */ --space-sm: clamp(0.5rem, 1vw, 1rem); --space-md: clamp(1rem, 3vw, 2rem); --space-lg: clamp(2rem, 5vw, 4rem); } h1 { font-size: var(--heading-1); } h2 { font-size: var(--heading-2); } p { font-size: var(--body-text); } /* 响应式容器 */ .container { width: clamp(320px, 90vw, 1400px); padding-inline: clamp(1rem, 5vw, 3rem); }
高级数学函数(CSS Values Level 4)
css/* 三角函数 */ .circular-motion { --angle: 45deg; transform: translate( calc(cos(var(--angle)) * 100px), calc(sin(var(--angle)) * 100px) ); } /* 指数和对数 */ .exponential-scale { --level: 3; font-size: calc(1rem * pow(1.25, var(--level))); } /* 取整函数 */ .grid-aligned { width: round(nearest, 100%, 8px); /* 对齐到 8px 网格 */ } /* 符号和绝对值 */ .dynamic-spacing { --offset: -20px; margin: abs(var(--offset)); /* 始终为正值 */ }
颜色函数:从 RGB 到 OKLCH
传统颜色函数
css.traditional-colors { /* RGB/RGBA */ color: rgb(59, 130, 246); background: rgba(59, 130, 246, 0.5); /* HSL/HSLA - 更直观的颜色模型 */ color: hsl(217, 91%, 60%); background: hsla(217, 91%, 60%, 0.5); /* 现代语法(空格分隔 + 斜杠透明度)*/ color: rgb(59 130 246); background: rgb(59 130 246 / 0.5); color: hsl(217 91% 60% / 0.8); }
现代颜色空间
css/* OKLCH - 感知均匀的颜色空间 */ :root { /* oklch(亮度 色度 色相 / 透明度) */ --primary: oklch(0.6 0.15 250); /* 蓝色 */ --primary-light: oklch(0.8 0.1 250); /* 浅蓝 */ --primary-dark: oklch(0.4 0.15 250); /* 深蓝 */ /* 通过调整亮度生成色阶 */ --gray-100: oklch(0.95 0 0); --gray-200: oklch(0.90 0 0); --gray-300: oklch(0.80 0 0); --gray-400: oklch(0.70 0 0); --gray-500: oklch(0.60 0 0); --gray-600: oklch(0.50 0 0); --gray-700: oklch(0.40 0 0); --gray-800: oklch(0.30 0 0); --gray-900: oklch(0.20 0 0); } /* Lab 颜色空间 */ .lab-colors { background: lab(50% 40 60); color: lch(70% 50 180); }
color-mix() - 颜色混合
css/* 基础混合 */ .color-mixing { /* 在 sRGB 空间混合 */ background: color-mix(in srgb, #3b82f6, white 20%); /* 在 OKLCH 空间混合(更平滑的过渡)*/ background: color-mix(in oklch, var(--primary), black 30%); } /* 动态主题色阶 */ :root { --brand: #3b82f6; --brand-50: color-mix(in oklch, var(--brand), white 90%); --brand-100: color-mix(in oklch, var(--brand), white 80%); --brand-200: color-mix(in oklch, var(--brand), white 60%); --brand-300: color-mix(in oklch, var(--brand), white 40%); --brand-400: color-mix(in oklch, var(--brand), white 20%); --brand-500: var(--brand); --brand-600: color-mix(in oklch, var(--brand), black 20%); --brand-700: color-mix(in oklch, var(--brand), black 40%); --brand-800: color-mix(in oklch, var(--brand), black 60%); --brand-900: color-mix(in oklch, var(--brand), black 80%); } /* 悬停效果 */ .button { background: var(--brand-500); &:hover { background: color-mix(in oklch, var(--brand-500), white 15%); } &:active { background: color-mix(in oklch, var(--brand-500), black 15%); } }
相对颜色语法
css/* 基于现有颜色创建变体 */ :root { --primary: #3b82f6; /* 调整亮度 */ --primary-light: oklch(from var(--primary) calc(l + 0.2) c h); --primary-dark: oklch(from var(--primary) calc(l - 0.2) c h); /* 调整饱和度 */ --primary-muted: oklch(from var(--primary) l calc(c * 0.5) h); --primary-vivid: oklch(from var(--primary) l calc(c * 1.5) h); /* 调整透明度 */ --primary-transparent: oklch(from var(--primary) l c h / 0.5); /* 色相旋转 */ --complement: oklch(from var(--primary) l c calc(h + 180)); --triadic-1: oklch(from var(--primary) l c calc(h + 120)); --triadic-2: oklch(from var(--primary) l c calc(h + 240)); }
自定义属性函数:var() 的高级用法
基础用法与回退值
css:root { --primary: #3b82f6; --spacing: 1rem; } .component { /* 基础使用 */ color: var(--primary); /* 带回退值 */ background: var(--bg-color, white); /* 嵌套回退 */ padding: var(--custom-padding, var(--spacing, 16px)); }
动态计算系统
css/* 基于变量的设计系统 */ :root { --base-size: 4px; --scale-ratio: 1.25; } /* 间距系统 */ .spacing-system { --space-1: var(--base-size); --space-2: calc(var(--base-size) * 2); --space-3: calc(var(--base-size) * 3); --space-4: calc(var(--base-size) * 4); --space-6: calc(var(--base-size) * 6); --space-8: calc(var(--base-size) * 8); --space-12: calc(var(--base-size) * 12); --space-16: calc(var(--base-size) * 16); } /* 类型比例尺 */ .type-scale { --text-xs: calc(1rem / var(--scale-ratio) / var(--scale-ratio)); --text-sm: calc(1rem / var(--scale-ratio)); --text-base: 1rem; --text-lg: calc(1rem * var(--scale-ratio)); --text-xl: calc(1rem * var(--scale-ratio) * var(--scale-ratio)); --text-2xl: calc(1rem * var(--scale-ratio) * var(--scale-ratio) * var(--scale-ratio)); }
条件样式与状态管理
css/* 使用空间切换技巧实现条件样式 */ .toggle-button { --is-active: 0; /* 0 = false, 1 = true */ background: hsl( calc(200 + var(--is-active) * 20) calc(50% + var(--is-active) * 30%) calc(50% + var(--is-active) * 10%) ); transform: scale(calc(1 + var(--is-active) * 0.05)); } .toggle-button[aria-pressed="true"] { --is-active: 1; } /* 主题切换 */ :root { --is-dark: 0; --bg: hsl(0 0% calc(100% - var(--is-dark) * 90%)); --text: hsl(0 0% calc(var(--is-dark) * 90%)); } [data-theme="dark"] { --is-dark: 1; }
渐变函数:视觉魔法
线性渐变高级技巧
css/* 多色渐变 */ .multi-color { background: linear-gradient( 135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #f5576c 75%, #ffd93d 100% ); } /* 硬边渐变(条纹)*/ .stripes { background: linear-gradient( 45deg, #3b82f6 25%, transparent 25%, transparent 50%, #3b82f6 50%, #3b82f6 75%, transparent 75% ); background-size: 20px 20px; } /* 渐变文字 */ .gradient-text { background: linear-gradient(135deg, #667eea, #764ba2); background-clip: text; -webkit-background-clip: text; color: transparent; }
径向和锥形渐变
css/* 径向渐变 */ .radial-examples { /* 聚光灯效果 */ background: radial-gradient( circle at 30% 30%, rgba(255,255,255,0.3) 0%, transparent 60% ); /* 椭圆渐变 */ background: radial-gradient( ellipse 80% 50% at center, #3b82f6, transparent ); } /* 锥形渐变 */ .conic-examples { /* 饼图效果 */ background: conic-gradient( #3b82f6 0deg 120deg, #10b981 120deg 240deg, #f59e0b 240deg 360deg ); /* 彩虹圆环 */ background: conic-gradient( from 45deg, red, orange, yellow, green, blue, purple, red ); /* 扫描效果 */ background: conic-gradient( from var(--angle), transparent 0deg, #3b82f6 30deg, transparent 60deg ); }
变换函数:2D 和 3D
css/* 2D 变换 */ .transform-2d { /* 单独使用 */ transform: translateX(100px); transform: rotate(45deg); transform: scale(1.5); transform: skewX(10deg); /* 组合变换(顺序重要!)*/ transform: translate(-50%, -50%) rotate(45deg) scale(1.2); } /* 3D 变换 */ .transform-3d { transform-style: preserve-3d; perspective: 1000px; transform: rotateX(30deg) rotateY(45deg) translateZ(100px); } /* 翻转卡片效果 */ .flip-card { perspective: 1000px; .card-inner { transform-style: preserve-3d; transition: transform 0.6s; } &:hover .card-inner { transform: rotateY(180deg); } .card-front, .card-back { backface-visibility: hidden; } .card-back { transform: rotateY(180deg); } }
滤镜函数:图像处理
css/* 单个滤镜 */ .filter-single { filter: blur(5px); filter: brightness(1.2); filter: contrast(1.5); filter: grayscale(100%); filter: hue-rotate(90deg); filter: saturate(2); filter: sepia(100%); filter: drop-shadow(0 4px 6px rgba(0,0,0,0.3)); } /* 组合滤镜 */ .filter-combo { filter: brightness(1.1) contrast(1.1) saturate(1.2); } /* 实用滤镜预设 */ .vintage { filter: sepia(0.4) contrast(1.1) brightness(0.9) saturate(0.8); } .cinematic { filter: contrast(1.2) saturate(0.8) brightness(0.95); } .dreamy { filter: blur(1px) brightness(1.1) saturate(1.3); } /* 背景模糊 */ .glass-effect { backdrop-filter: blur(10px) saturate(180%); background: rgba(255, 255, 255, 0.2); }
即将到来:@function 自定义函数
CSS 正在引入真正的自定义函数能力,这将彻底改变 CSS 的编写方式:
css/* CSS 自定义函数(提案阶段)*/ @function --fluid-size(--min, --max, --min-vw: 320px, --max-vw: 1200px) { --slope: calc((var(--max) - var(--min)) / (var(--max-vw) - var(--min-vw))); --intercept: calc(var(--min) - var(--slope) * var(--min-vw)); @return clamp( var(--min), calc(var(--intercept) + var(--slope) * 100vw), var(--max) ); } /* 使用自定义函数 */ h1 { font-size: --fluid-size(24px, 48px); } /* 颜色操作函数 */ @function --lighten(--color, --amount: 10%) { @return color-mix(in oklch, var(--color), white var(--amount)); } @function --darken(--color, --amount: 10%) { @return color-mix(in oklch, var(--color), black var(--amount)); } .button { background: var(--primary); &:hover { background: --lighten(var(--primary), 15%); } } /* 间距计算函数 */ @function --space(--multiplier) { @return calc(var(--base-spacing, 4px) * var(--multiplier)); } .card { padding: --space(4); margin-bottom: --space(6); gap: --space(2); }
实战:构建设计系统
css/* 完整的函数式设计系统 */ :root { /* 基础配置 */ --base-size: 4px; --base-font: 16px; --scale: 1.25; /* 颜色系统 */ --hue-primary: 220; --hue-success: 142; --hue-warning: 38; --hue-error: 0; /* 生成颜色 */ --primary: oklch(0.55 0.15 var(--hue-primary)); --success: oklch(0.55 0.15 var(--hue-success)); --warning: oklch(0.55 0.15 var(--hue-warning)); --error: oklch(0.55 0.15 var(--hue-error)); /* 间距比例尺 */ --space-1: var(--base-size); --space-2: calc(var(--base-size) * 2); --space-3: calc(var(--base-size) * 3); --space-4: calc(var(--base-size) * 4); --space-5: calc(var(--base-size) * 5); --space-6: calc(var(--base-size) * 6); --space-8: calc(var(--base-size) * 8); --space-10: calc(var(--base-size) * 10); --space-12: calc(var(--base-size) * 12); --space-16: calc(var(--base-size) * 16); /* 字体比例尺 */ --text-xs: calc(var(--base-font) / var(--scale) / var(--scale)); --text-sm: calc(var(--base-font) / var(--scale)); --text-base: var(--base-font); --text-lg: calc(var(--base-font) * var(--scale)); --text-xl: calc(var(--base-font) * var(--scale) * var(--scale)); --text-2xl: calc(var(--base-font) * var(--scale) * var(--scale) * var(--scale)); --text-3xl: calc(var(--base-font) * var(--scale) * var(--scale) * var(--scale) * var(--scale)); /* 流体字体 */ --fluid-sm: clamp(var(--text-xs), 0.8vw + 0.5rem, var(--text-sm)); --fluid-base: clamp(var(--text-sm), 1vw + 0.5rem, var(--text-base)); --fluid-lg: clamp(var(--text-base), 1.5vw + 0.5rem, var(--text-lg)); --fluid-xl: clamp(var(--text-lg), 2vw + 0.5rem, var(--text-xl)); --fluid-2xl: clamp(var(--text-xl), 3vw + 0.5rem, var(--text-2xl)); /* 圆角 */ --radius-sm: calc(var(--base-size) * 1); --radius-md: calc(var(--base-size) * 2); --radius-lg: calc(var(--base-size) * 3); --radius-xl: calc(var(--base-size) * 4); --radius-full: 9999px; /* 阴影 */ --shadow-sm: 0 1px 2px color-mix(in oklch, black, transparent 95%); --shadow-md: 0 4px 6px color-mix(in oklch, black, transparent 90%); --shadow-lg: 0 10px 15px color-mix(in oklch, black, transparent 85%); --shadow-xl: 0 20px 25px color-mix(in oklch, black, transparent 80%); } /* 组件示例 */ .button { padding: var(--space-2) var(--space-4); font-size: var(--fluid-base); border-radius: var(--radius-md); background: var(--primary); color: white; box-shadow: var(--shadow-sm); transition: all 0.2s ease; &:hover { background: color-mix(in oklch, var(--primary), white 15%); box-shadow: var(--shadow-md); transform: translateY(-1px); } &:active { background: color-mix(in oklch, var(--primary), black 10%); transform: translateY(0); } } .card { padding: var(--space-6); border-radius: var(--radius-lg); background: white; box-shadow: var(--shadow-md); .card-title { font-size: var(--fluid-lg); margin-bottom: var(--space-2); } .card-content { font-size: var(--fluid-base); color: color-mix(in oklch, black, transparent 40%); } }
浏览器兼容性与渐进增强
css/* 使用 @supports 检测功能支持 */ .modern-color { /* 回退值 */ background: #3b82f6; /* 现代浏览器 */ @supports (background: oklch(0.5 0.15 250)) { background: oklch(0.5 0.15 250); } } /* color-mix 回退 */ .hover-effect { background: #3b82f6; &:hover { background: #60a5fa; /* 手动计算的回退值 */ @supports (background: color-mix(in oklch, red, blue)) { background: color-mix(in oklch, #3b82f6, white 20%); } } } /* 相对颜色语法回退 */ :root { --primary: #3b82f6; --primary-light: #60a5fa; /* 回退值 */ @supports (color: oklch(from red l c h)) { --primary-light: oklch(from var(--primary) calc(l + 0.15) c h); } }
总结
"CSS 函数已经从简单的 url() 和 rgb() 发展成为一个完整的函数式编程体系。掌握这些函数,你就能用更少的代码实现更强大、更灵活的样式系统。
CSS 函数的演进历程:
2010s: rgb(), url(), linear-gradient()
↓
2015s: calc(), var()
↓
2020s: min(), max(), clamp(), color-mix()
↓
2025+: @function, oklch(), 相对颜色语法
现代 CSS 已经不再是「只能写静态样式」的语言。通过合理运用函数,我们可以构建出响应式、可维护、高性能的设计系统。拥抱 CSS 函数,让你的样式代码更加优雅强大!



