三种渐变类型,本质都是"颜色插值"
CSS 支持三种渐变:linear-gradient(线性)、radial-gradient(径向)、conic-gradient(圆锥)。它们的核心机制是一样的——在起点和终点之间进行颜色插值。
线性渐变:最简单也最常用
/* 最简形式 */
background: linear-gradient(#667eea, #764ba2);
/* 指定方向 */
background: linear-gradient(135deg, #667eea, #764ba2);
/* 多个颜色节点 */
background: linear-gradient(90deg, #ff6b6b, #feca57, #ff9ff3);
线性渐变的关键参数是角度。0deg 是从下往上,90deg 是从左往右,135deg 是左下到右上。这个角度定义的是渐变线的方向,颜色沿着这条线分布。
角度计算有个容易踩的坑:CSS 的角度是顺时针的,但数学上的角度是逆时针的。所以 linear-gradient(45deg) 和 SVG 的 transform="rotate(45)" 方向是一致的,但和 Canvas 的 rotate() 相反。
径向渐变:从中心向外扩散
/* 圆形径向渐变 */
background: radial-gradient(circle, #48dbfb, #006ba6);
/* 椭圆形 */
background: radial-gradient(ellipse, #1dd1a1, #10ac84);
/* 指定圆心位置 */
background: radial-gradient(circle at 30% 70%, #5f27cd, #341f97);
径向渐变的形状由 circle 或 ellipse 决定。at 关键字指定圆心位置,可以是百分比、像素值或关键字(center、top left 等)。
实现径向渐变时,我发现一个有趣的边界情况:当容器是正方形时,circle 和 ellipse 看起来一样;但当容器是长方形时,ellipse 会自动拉伸以填满容器,而 circle 保持正圆。
圆锥渐变:围绕中心点旋转
/* 基础圆锥渐变 */
background: conic-gradient(#ff6348, #ff4757, #ffa502, #ff6348);
/* 指定起始角度 */
background: conic-gradient(from 45deg, #00d2d3, #5f27cd, #ff9ff3, #00d2d3);
/* 指定中心点 */
background: conic-gradient(from 0deg at 50% 50%, #2f3542, #57606f, #747d8c, #2f3542);
圆锥渐变是 CSS Images Module Level 4 新增的,用于创建类似雷达图或饼图的效果。颜色围绕中心点旋转分布,from 指定起始角度。
注意圆锥渐变的最后一个颜色必须和第一个颜色相同,否则会有明显的接缝。这是因为渐变是 360 度闭环的。
颜色节点的高级用法
指定位置
颜色节点可以指定具体位置,精确控制渐变过渡:
/* 颜色在 30% 和 70% 处过渡 */
background: linear-gradient(90deg,
#667eea 0%,
#764ba2 30%,
#ff9ff3 70%,
#feca57 100%
);
硬边缘
如果两个颜色节点位置相同,就没有过渡,形成硬边缘:
/* 条纹效果 */
background: linear-gradient(90deg,
#667eea 0%, #667eea 25%,
#764ba2 25%, #764ba2 50%,
#ff9ff3 50%, #ff9ff3 75%,
#feca57 75%, #feca57 100%
);
这个技巧常用于创建条纹背景、格子图案。
透明度渐变
渐变支持 rgba() 或 #rrggbbaa 格式,实现透明度过渡:
/* 从透明到不透明 */
background: linear-gradient(180deg,
rgba(102, 126, 234, 0),
rgba(118, 75, 162, 1)
);
这在做遮罩层、图片上方的文字背景时特别有用。
实现在线生成器的技术细节
实时预览
核心是监听颜色、角度、类型的变化,实时计算 CSS 字符串:
const generateGradient = useCallback(() => {
const colorStops = colors.join(', ')
switch (gradientType) {
case 'linear':
return `linear-gradient(${angle}deg, ${colorStops})`
case 'radial':
return `radial-gradient(circle, ${colorStops})`
case 'conic':
return `conic-gradient(from ${angle}deg, ${colorStops})`
}
}, [colors, gradientType, angle])
随机渐变
生成随机颜色时,我用了一个简单但有效的方法:
const randomColor = () => {
return '#' + Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, '0')
}
16777215 是 0xFFFFFF,即 24 位颜色的最大值。padStart(6, '0') 确保不足 6 位时前面补零。
但纯随机生成的颜色往往不好看。更好的方法是使用 HSL 色彩空间,限制饱和度和亮度范围:
const randomColorHSL = () => {
const h = Math.floor(Math.random() * 360)
const s = 60 + Math.floor(Math.random() * 30) // 60-90%
const l = 50 + Math.floor(Math.random() * 20) // 50-70%
return `hsl(${h}, ${s}%, ${l}%)`
}
这样生成的颜色更鲜艳、更协调。
预设渐变
我收集了一些常用的渐变组合:
const PRESET_GRADIENTS = [
{ name: '日落', colors: ['#ff6b6b', '#feca57', '#ff9ff3'] },
{ name: '海洋', colors: ['#48dbfb', '#0abde3', '#006ba6'] },
{ name: '森林', colors: ['#1dd1a1', '#10ac84', '#00d2d3'] },
{ name: '紫霞', colors: ['#5f27cd', '#341f97', '#9980fa'] },
]
这些预设来自 UI Gradients 等网站,都是设计师精选的配色。
浏览器兼容性
现代浏览器对三种渐变的支持都很好:
linear-gradient: IE10+,所有现代浏览器radial-gradient: IE10+,所有现代浏览器conic-gradient: Chrome 69+, Firefox 83+, Safari 12.1+
如果需要支持旧浏览器,可以用 linear-gradient 作为 fallback:
background: #667eea;
background: conic-gradient(from 45deg, #667eea, #764ba2);
性能优化
渐变本身是 GPU 加速的,性能开销很小。但有几个注意点:
- 避免过多颜色节点:每个节点都会增加计算量,一般不超过 5 个
- 避免频繁更新:如果渐变需要动画,用 CSS
@property而不是 JS - 大容器慎用径向渐变:径向渐变需要计算每个像素到圆心的距离,大容器可能卡顿
最终工具
基于以上研究,我做了一个 CSS 渐变生成器:
- 支持线性、径向、圆锥三种类型
- 实时预览 + CSS 代码生成
- 8 个精选预设渐变
- 随机生成功能
核心代码不到 200 行,但把 CSS gradient 的各种用法都覆盖了。希望这篇文章能帮你理解渐变的原理,下次遇到复杂渐变需求时不再迷茫。
相关工具:CSS 变量生成器 | Flexbox 生成器