渐变
深入解析 CSS 渐变(linear-gradient、radial-gradient、conic-gradient)的规范、几何算法、颜色插值与工程实践
前置知识
建议先阅读以下内容再进入本文:
0基础速通:读第 0 节直觉与第 1 节核心必读(代码示例)即可;第 6 章深入理解(选读)供进阶。
渐变(Gradients)
本文以 W3C CSS Images Module Level 3 与 CSS Images Module Level 4 规范为基础,系统阐释 CSS 渐变(Gradients)的几何算法、颜色插值(Color Interpolation)、
linear-gradient/radial-gradient/conic-gradient/repeating-*的形式化定义,以及与 SVG 渐变、Tailwind / Bootstrap / Material Design 等框架实践的对接。内容涵盖从 CSS 3(2012)到 CSS Images Level 4(2024)的演进,提供生产级代码示例与工程化解决方案。
0. 直觉:渐变就是“颜色之间的过渡”
渐变的本质是让颜色从一个点平滑过渡到另一个点:线性渐变沿一条直线过渡(linear-gradient),径向渐变从圆心向外扩散(radial-gradient),锥形渐变绕一圈过渡(conic-gradient)。
先记住一个最小模型:background: linear-gradient(方向, 起点色, 终点色)。剩下的参数(角度、色标、重复)都是在这个模型上加细节。
1. 核心必读:代码示例
1.1 基础示例:线性渐变
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>线性渐变基础示例</title>
<style>
.gradient-basic {
width: 300px;
height: 100px;
/* 从左到右,红到蓝 */
background: linear-gradient(to right, red, blue);
margin: 10px 0;
}
.gradient-angle {
width: 300px;
height: 100px;
/* 45deg 角度 */
background: linear-gradient(45deg, #667eea, #764ba2);
margin: 10px 0;
}
.gradient-multi-stop {
width: 300px;
height: 100px;
/* 多色标 */
background: linear-gradient(to right, red 0%, yellow 50%, blue 100%);
margin: 10px 0;
}
.gradient-hard-stop {
width: 300px;
height: 100px;
/* 硬边界 */
background: linear-gradient(to right, red 50%, blue 50%);
margin: 10px 0;
}
.gradient-hard-stop-v2 {
width: 300px;
height: 100px;
/* Level 4 双色标语法 */
background: linear-gradient(to right, red 25% 50%, blue 50% 75%);
margin: 10px 0;
}
</style>
</head>
<body>
<div class="gradient-basic"></div>
<div class="gradient-angle"></div>
<div class="gradient-multi-stop"></div>
<div class="gradient-hard-stop"></div>
<div class="gradient-hard-stop-v2"></div>
</body>
</html>
讲解:
linear-gradient(to right, red, blue)从左到右过渡,方向关键词可用角度(45deg)替代;- 多色标写法
linear-gradient(red, yellow, blue)让颜色分段过渡; - “硬边界”用相同位置的色标实现(如
red 50%, blue 50%),是条纹与分隔效果的基础。
1.2 重复线性渐变:条纹纹理
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>重复线性渐变:条纹纹理</title>
<style>
.stripes-diagonal {
width: 300px;
height: 200px;
/* 45deg 对角条纹 */
background: repeating-linear-gradient(
45deg,
#fff 0px,
#fff 10px,
#000 10px,
#000 20px
);
}
.stripes-vertical {
width: 300px;
height: 200px;
/* 垂直条纹 */
background: repeating-linear-gradient(
to right,
#667eea 0px,
#667eea 20px,
#764ba2 20px,
#764ba2 40px
);
}
.checkerboard {
width: 300px;
height: 300px;
/* 棋盘格:两层渐变叠加 */
background:
repeating-linear-gradient(0deg, transparent 0, transparent 40px, #000 40px, #000 80px),
repeating-linear-gradient(90deg, transparent 0, transparent 40px, #000 40px, #000 80px);
background-color: #fff;
}
</style>
</head>
<body>
<div class="stripes-diagonal"></div>
<div class="stripes-vertical"></div>
<div class="checkerboard"></div>
</body>
</html>
1.3 径向渐变:光晕效果
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>径向渐变:光晕效果</title>
<style>
.halo {
width: 300px;
height: 300px;
/* 圆形径向渐变,从中心透明到边缘不透明 */
background: radial-gradient(
circle at center,
transparent 0%,
transparent 30%,
rgba(102, 126, 234, 0.5) 60%,
rgba(118, 75, 162, 0.8) 100%
);
}
.spotlight {
width: 300px;
height: 300px;
/* 椭圆径向渐变,模拟聚光灯 */
background: radial-gradient(
ellipse 80% 50% at 50% 50%,
rgba(255, 255, 255, 0.9) 0%,
rgba(255, 255, 255, 0.3) 40%,
transparent 70%
);
background-color: #1a1a2e;
}
.vignette {
width: 300px;
height: 200px;
/* 暗角效果 */
background: radial-gradient(
circle at center,
transparent 50%,
rgba(0, 0, 0, 0.8) 100%
);
background-color: #4a90e2;
}
</style>
</head>
<body>
<div class="halo"></div>
<div class="spotlight"></div>
<div class="vignette"></div>
</body>
</html>
1.4 径向渐变尺寸关键字
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>径向渐变尺寸关键字对比</title>
<style>
.box {
width: 200px;
height: 150px;
display: inline-block;
margin: 5px;
border: 1px solid #ccc;
}
.closest-side {
background: radial-gradient(circle closest-side at 30% 40%, red, blue);
}
.farthest-side {
background: radial-gradient(circle farthest-side at 30% 40%, red, blue);
}
.closest-corner {
background: radial-gradient(circle closest-corner at 30% 40%, red, blue);
}
.farthest-corner {
background: radial-gradient(circle farthest-corner at 30% 40%, red, blue);
}
</style>
</head>
<body>
<div class="box closest-side">closest-side</div>
<div class="box farthest-side">farthest-side</div>
<div class="box closest-corner">closest-corner</div>
<div class="box farthest-corner">farthest-corner(默认)</div>
</body>
</html>
1.5 锥形渐变:饼图与色轮
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>锥形渐变:饼图与色轮</title>
<style>
.pie-chart {
width: 200px;
height: 200px;
border-radius: 50%;
/* 饼图:30% 红,30% 黄,40% 绿 */
background: conic-gradient(
red 0% 30%,
yellow 30% 60%,
green 60% 100%
);
}
.color-wheel {
width: 200px;
height: 200px;
border-radius: 50%;
/* 色轮:红→黄→绿→青→蓝→品红→红 */
background: conic-gradient(
red,
yellow,
lime,
aqua,
blue,
magenta,
red
);
}
.progress-ring {
width: 200px;
height: 200px;
border-radius: 50%;
/* 进度环:75% 完成 */
background: conic-gradient(
#4caf50 0% 75%,
#e0e0e0 75% 100%
);
position: relative;
}
/* 中心镂空 */
.progress-ring::before {
content: '';
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
background: white;
border-radius: 50%;
}
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
font-weight: bold;
z-index: 1;
}
</style>
</head>
<body>
<div class="pie-chart"></div>
<div class="color-wheel"></div>
<div class="progress-ring">
<span class="progress-text">75%</span>
</div>
</body>
</html>
1.6 渐变文字
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>渐变文字效果</title>
<style>
.gradient-text {
font-size: 48px;
font-weight: bold;
background: linear-gradient(to right, #667eea, #764ba2);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent; /* 兜底 */
}
.gradient-text-rainbow {
font-size: 36px;
font-weight: bold;
background: linear-gradient(
to right,
#ff0080,
#ff8c00,
#ffd700,
#00ff00,
#00bfff,
#8a2be2
);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* 可访问性:高对比度模式下移除渐变 */
@media (prefers-contrast: more) {
.gradient-text,
.gradient-text-rainbow {
-webkit-text-fill-color: initial;
color: #667eea;
background: none;
}
}
</style>
</head>
<body>
<h1 class="gradient-text">渐变文字示例</h1>
<h2 class="gradient-text-rainbow">彩虹渐变文字</h2>
</body>
</html>
1.7 渐变边框
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>渐变边框效果</title>
<style>
.gradient-border {
padding: 20px;
border: 2px solid transparent;
/* 双背景:内层白色 + 外层渐变 */
background:
linear-gradient(white, white) padding-box,
linear-gradient(to right, #667eea, #764ba2) border-box;
border-radius: 8px;
}
.gradient-border-rounded {
padding: 20px;
border: 3px solid transparent;
border-radius: 50%;
background:
linear-gradient(white, white) padding-box,
conic-gradient(from 0deg, #ff0080, #ff8c00, #ffd700, #00ff00, #00bfff, #8a2be2, #ff0080) border-box;
}
.gradient-border-thick {
padding: 20px;
border: 10px solid transparent;
background:
linear-gradient(white, white) padding-box,
linear-gradient(135deg, #667eea, #764ba2, #f093fb) border-box;
border-radius: 12px;
}
</style>
</head>
<body>
<div class="gradient-border">渐变边框(细)</div>
<div class="gradient-border-rounded">圆形渐变边框</div>
<div class="gradient-border-thick">渐变边框(粗)</div>
</body>
</html>
1.8 Oklab 插值对比
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Oklab vs sRGB 插值对比</title>
<style>
.box {
width: 100%;
height: 80px;
margin: 10px 0;
}
/* 默认 sRGB 插值 */
.srgb-gradient {
background: linear-gradient(to right, red, blue);
}
/* Oklab 插值(更平滑) */
.oklab-gradient {
background: linear-gradient(in oklab, red, blue);
}
/* LCH 较短色相 */
.lch-short {
background: linear-gradient(in oklch shorter hue, red, blue);
}
/* LCH 较长色相 */
.lch-long {
background: linear-gradient(in oklch longer hue, red, blue);
}
/* 暗部对比:sRGB 易出现色带 */
.srgb-dark {
background: linear-gradient(to right, #000, #333);
}
.oklab-dark {
background: linear-gradient(in oklab, #000, #333);
}
label {
display: block;
font-family: monospace;
margin-top: 20px;
font-weight: bold;
}
</style>
</head>
<body>
<label>sRGB: linear-gradient(to right, red, blue)</label>
<div class="box srgb-gradient"></div>
<label>Oklab: linear-gradient(in oklab, red, blue)</label>
<div class="box oklab-gradient"></div>
<label>Oklch shorter hue: red → blue(经过品红)</label>
<div class="box lch-short"></div>
<label>Oklch longer hue: red → blue(经过黄绿青)</label>
<div class="box lch-long"></div>
<label>sRGB 暗部(易出现色带)</label>
<div class="box srgb-dark"></div>
<label>Oklab 暗部(更平滑)</label>
<div class="box oklab-dark"></div>
</body>
</html>
1.9 多层渐变叠加
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>多层渐变叠加</title>
<style>
.complex-background {
width: 400px;
height: 300px;
/* 三层渐变叠加:
* 1. 顶层:径向光晕
* 2. 中层:对角条纹
* 3. 底层:线性渐变
*/
background:
radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.3), transparent 50%),
repeating-linear-gradient(
45deg,
transparent 0px,
transparent 20px,
rgba(255, 255, 255, 0.1) 20px,
rgba(255, 255, 255, 0.1) 40px
),
linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.mesh-gradient {
width: 400px;
height: 300px;
/* 模拟网格渐变(mesh gradient):
* 多个径向渐变叠加,模拟平滑过渡
*/
background:
radial-gradient(at 0% 0%, #ff0080 0%, transparent 50%),
radial-gradient(at 100% 0%, #ff8c00 0%, transparent 50%),
radial-gradient(at 0% 100%, #00bfff 0%, transparent 50%),
radial-gradient(at 100% 100%, #8a2be2 0%, transparent 50%),
#1a1a2e;
}
</style>
</head>
<body>
<div class="complex-background"></div>
<div class="mesh-gradient"></div>
</body>
</html>
1.10 企业级:可主题化渐变系统
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>企业级可主题化渐变系统</title>
<style>
:root {
/* 渐变设计令牌 */
--gradient-primary: linear-gradient(135deg, #667eea, #764ba2);
--gradient-success: linear-gradient(135deg, #4caf50, #81c784);
--gradient-danger: linear-gradient(135deg, #f44336, #e57373);
--gradient-warning: linear-gradient(135deg, #ff9800, #ffb74d);
--gradient-info: linear-gradient(135deg, #2196f3, #64b5f6);
/* 渐变方向令牌 */
--gradient-direction: 135deg;
}
/* 深色主题 */
[data-theme="dark"] {
--gradient-primary: linear-gradient(135deg, #4c51bf, #553c9a);
--gradient-success: linear-gradient(135deg, #38a169, #48bb78);
--gradient-danger: linear-gradient(135deg, #e53e3e, #fc8181);
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 6px;
color: white;
font-size: 14px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.btn-primary { background: var(--gradient-primary); }
.btn-success { background: var(--gradient-success); }
.btn-danger { background: var(--gradient-danger); }
.btn-warning { background: var(--gradient-warning); }
.btn-info { background: var(--gradient-info); }
/* 动态渐变:通过 CSS 变量组合 */
.btn-dynamic {
background: linear-gradient(
var(--gradient-direction),
var(--color-start, #667eea),
var(--color-end, #764ba2)
);
}
.card {
padding: 24px;
border-radius: 12px;
background: var(--gradient-primary);
color: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<button class="btn btn-primary">主按钮</button>
<button class="btn btn-success">成功</button>
<button class="btn btn-danger">危险</button>
<button class="btn btn-warning">警告</button>
<button class="btn btn-info">信息</button>
</div>
<div style="margin-top: 24px;">
<div class="card">
<h3>渐变卡片</h3>
<p>使用设计令牌管理的渐变背景</p>
</div>
</div>
<button class="btn btn-dynamic"
style="--color-start: #ff0080; --color-end: #ff8c00; --gradient-direction: to right;">
动态渐变按钮
</button>
</body>
</html>
1.11 渐变动画
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>渐变动画</title>
<style>
/* 方案 1:通过 background-position 动画 */
.animated-gradient {
width: 400px;
height: 100px;
background: linear-gradient(
90deg,
#667eea,
#764ba2,
#f093fb,
#667eea
);
background-size: 300% 100%;
animation: gradient-shift 3s ease infinite;
}
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* 方案 2:通过 @property 动画色标(CSS Houdini) */
@property --gradient-color-1 {
syntax: '<color>';
initial-value: #667eea;
inherits: false;
}
@property --gradient-color-2 {
syntax: '<color>';
initial-value: #764ba2;
inherits: false;
}
.houdini-gradient {
width: 400px;
height: 100px;
background: linear-gradient(
to right,
var(--gradient-color-1),
var(--gradient-color-2)
);
animation: color-shift 4s ease infinite alternate;
}
@keyframes color-shift {
0% {
--gradient-color-1: #667eea;
--gradient-color-2: #764ba2;
}
100% {
--gradient-color-1: #f093fb;
--gradient-color-2: #f5576c;
}
}
/* 尊重用户运动偏好 */
@media (prefers-reduced-motion: reduce) {
.animated-gradient,
.houdini-gradient {
animation: none;
}
}
</style>
</head>
<body>
<div class="animated-gradient"></div>
<div class="houdini-gradient"></div>
</body>
</html>
1.12 渐变可视化工具
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>渐变可视化工具</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 800px;
margin: 2rem auto;
padding: 0 1rem;
}
.preview {
width: 100%;
height: 200px;
border-radius: 8px;
border: 1px solid #dee2e6;
margin: 1rem 0;
}
.controls {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 8px;
}
label {
display: block;
font-size: 0.875rem;
color: #6c757d;
margin-bottom: 0.25rem;
}
input, select {
width: 100%;
padding: 0.5rem;
border: 1px solid #ced4da;
border-radius: 4px;
font-family: monospace;
}
.output {
padding: 1rem;
background: #212529;
color: #f8f9fa;
border-radius: 4px;
font-family: monospace;
word-break: break-all;
}
</style>
</head>
<body>
<h1>渐变可视化工具</h1>
<div class="preview" id="preview"></div>
<div class="controls">
<div>
<label>渐变类型</label>
<select id="type">
<option value="linear">linear-gradient</option>
<option value="radial">radial-gradient</option>
<option value="conic">conic-gradient</option>
</select>
</div>
<div>
<label>角度 / 位置</label>
<input id="angle" value="45deg">
</div>
<div>
<label>起始颜色</label>
<input id="color1" value="#667eea">
</div>
<div>
<label>结束颜色</label>
<input id="color2" value="#764ba2">
</div>
<div>
<label>插值色彩空间</label>
<select id="interp">
<option value="">默认 sRGB</option>
<option value="in oklab">in oklab</option>
<option value="in oklch">in oklch</option>
<option value="in lab">in lab</option>
<option value="in lch">in lch</option>
</select>
</div>
</div>
<div class="output" id="output">linear-gradient(45deg, #667eea, #764ba2)</div>
<script>
function updateGradient() {
const type = document.getElementById('type').value;
const angle = document.getElementById('angle').value;
const color1 = document.getElementById('color1').value;
const color2 = document.getElementById('color2').value;
const interp = document.getElementById('interp').value;
let gradient;
if (type === 'linear') {
gradient = `linear-gradient(${interp ? interp + ', ' : ''}${angle}, ${color1}, ${color2})`;
} else if (type === 'radial') {
gradient = `radial-gradient(${interp ? interp + ', ' : ''}circle at ${angle}, ${color1}, ${color2})`;
} else {
gradient = `conic-gradient(${interp ? interp + ', ' : ''}from ${angle} at 50% 50%, ${color1}, ${color2})`;
}
document.getElementById('preview').style.background = gradient;
document.getElementById('output').textContent = gradient;
}
document.querySelectorAll('input, select').forEach(el => {
el.addEventListener('input', updateGradient);
});
updateGradient();
</script>
</body>
</html>
2. 对比分析
2.1 CSS 渐变 vs SVG 渐变
| 维度 | CSS 渐变 | SVG 渐变 |
|---|---|---|
| 语法 | CSS 属性 background | XML <linearGradient> / <radialGradient> |
| 应用方式 | 直接 background: linear-gradient(...) | 通过 fill="url(#grad)" 引用 |
| 动画 | 有限(background-position 或 Houdini) | 支持 SMIL 与 CSS 动画 |
| 性能 | 浏览器优化,GPU 加速 | 需解析 XML,性能略低 |
| 可维护性 | 简洁,内联于 CSS | 需在 SVG 中定义,引用复杂 |
| 可访问性 | 同 CSS | 同 SVG,支持 ARIA |
| 适用场景 | 背景纹理、按钮、卡片 | 复杂矢量图形、图表 |
2.2 主流框架的渐变实践
| 框架 | 渐变工具类 | 自定义方式 |
|---|---|---|
| Bootstrap 5 | bg-gradient 修饰类 | 通过 Sass 变量 $gradient |
| Tailwind CSS v3.4 | bg-gradient-to-r from-blue-500 to-purple-500 | 通过 tailwind.config.js 扩展 |
| Material Design 3 | 主题色梯度 | 通过 mdc-theme-* 变量 |
| Ant Design 5 | linear-gradient 内联 | 通过 ConfigProvider 主题 |
| GitHub Primer | color-gradient-* 工具类 | 通过设计令牌 |
2.3 Tailwind vs Bootstrap 的渐变哲学
Tailwind CSS:
<!-- 原子工具类组合 -->
<button class="bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600">
按钮
</button>
- 优势:灵活,可在 HTML 中快速调整。
- 劣势:类名冗长,复用性弱。
Bootstrap 5:
<!-- 预定义渐变类 -->
<button class="btn btn-primary bg-gradient">
按钮
</button>
- 优势:简洁,语义清晰。
- 劣势:自定义渐变需修改 Sass 源码。
2.4 色彩空间插值对比
| 色彩空间 | 视觉效果 | 适用场景 | 浏览器支持 |
|---|---|---|---|
| sRGB(默认) | 暗部易出现色带 | 简单渐变、兼容性优先 | 全部 |
| linearRGB | 物理准确,略亮 | 物理仿真、光照效果 | Chrome 99+, Safari 16.2+ |
| Lab | 感知均匀,平滑 | 设计师审美、品牌色 | Chrome 111+, Safari 16.2+ |
| LCH | 色相旋转可控 | 色轮、彩虹渐变 | Chrome 111+, Safari 16.2+ |
| Oklab | 改进 Lab,更准确 | 现代首选 | Chrome 111+, Safari 16.2+ |
| OkLCH | 色相可控 + 感知均匀 | 现代设计系统首选 | Chrome 111+, Safari 16.2+ |
| HSL | 色相直接插值 | 简单色相过渡 | Chrome 99+, Safari 16.2+ |
| HWB | 色相 + 白黑分量 | 柔和过渡 | 实验性 |
2.5 渐变类型对比
| 渐变类型 | 几何模型 | 典型应用 | 浏览器支持 |
|---|---|---|---|
linear-gradient | 梯度线 | 背景、按钮、卡片 | 全部 |
radial-gradient | 渐变射线 | 光晕、聚光灯、阴影 | 全部 |
conic-gradient | 渐变弧 | 饼图、色轮、进度环 | Chrome 69+, Safari 12.1+, Firefox 83+ |
repeating-linear-gradient | 周期性梯度线 | 条纹纹理 | 全部 |
repeating-radial-gradient | 周期性渐变射线 | 同心圆纹理 | 全部 |
repeating-conic-gradient | 周期性渐变弧 | 放射状纹理 | Chrome 69+, Safari 12.1+ |
3. 常见陷阱与最佳实践
3.1 陷阱 1:色带效应
问题:长渐变中出现颜色断层。
/* 反例:sRGB 暗部渐变易出现色带 */
background: linear-gradient(to bottom, #000, #333);
最佳实践:使用 oklab 插值或叠加噪声。
/* 正例:oklab 插值 */
background: linear-gradient(in oklab, #000, #333);
/* 或叠加噪声 */
background:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><filter id="n"><feTurbulence baseFrequency="0.9"/></filter><rect width="100" height="100" filter="url(%23n)" opacity="0.05"/></svg>'),
linear-gradient(to bottom, #000, #333);
3.2 陷阱 2:硬边界滥用
问题:硬边界(Hard Stop)形成生硬分界,视觉突兀。
/* 反例:硬边界用于装饰 */
background: linear-gradient(to right, red 50%, blue 50%);
最佳实践:硬边界仅用于纹理或明确分块,装饰性渐变应平滑过渡。
3.3 陷阱 3:background-clip: text 兼容性
问题:background-clip: text 在旧浏览器不支持。
/* 反例:未提供兜底 */
.gradient-text {
background: linear-gradient(to right, red, blue);
-webkit-background-clip: text;
color: transparent; /* 旧浏览器显示透明文字 */
}
最佳实践:使用 -webkit-text-fill-color 并保留 color 兜底。
/* 正例:保留兜底 */
.gradient-text {
color: #667eea; /* 兜底色 */
background: linear-gradient(to right, #667eea, #764ba2);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
3.4 陷阱 4:渐变方向歧义
问题:to top right 与 45deg 的渐变方向不同。
/* to top right:从左下到右上 */
background: linear-gradient(to top right, red, blue);
/* 45deg:从下到上偏右 45° */
background: linear-gradient(45deg, red, blue);
最佳实践:理解规范定义,to <corner> 是「指向角落」,<angle> 是「梯度线方向」。
3.5 陷阱 5:径向渐变尺寸歧义
问题:未指定尺寸关键字时,farthest-corner 是默认值,可能不符合预期。
/* 默认 farthest-corner */
background: radial-gradient(circle at 30% 40%, red, blue);
/* 显式 closest-side */
background: radial-gradient(circle closest-side at 30% 40%, red, blue);
最佳实践:显式指定尺寸关键字,避免歧义。
3.6 陷阱 6:conic-gradient 接缝
问题:conic-gradient 首尾色标不同时形成接缝。
/* 反例:接缝明显 */
background: conic-gradient(red, yellow, lime, aqua, blue);
最佳实践:首尾使用相同颜色,或使用 from <angle> 调整起始位置。
/* 正例:首尾相同 */
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
3.7 陷阱 7:渐变动画性能
问题:通过 background-position 动画渐变可能触发重绘,性能差。
/* 反例:性能差 */
background: linear-gradient(90deg, red, blue);
background-size: 200% 100%;
animation: shift 3s infinite;
@keyframes shift {
to { background-position: 100% 0; }
}
最佳实践:使用 transform 或 opacity 动画,或使用 CSS Houdini @property。
/* 正例:Houdini @property */
@property --color1 {
syntax: '<color>';
initial-value: red;
inherits: false;
}
background: linear-gradient(90deg, var(--color1), blue);
animation: color 3s infinite;
@keyframes color {
to { --color1: green; }
}
3.8 陷阱 8:可访问性忽视
问题:渐变背景上文字对比度不足。
/* 反例:对比度不足 */
.text-on-gradient {
background: linear-gradient(to right, #667eea, #764ba2);
color: white; /* 部分位置对比度 < 4.5:1 */
}
最佳实践:使用对比度检查工具,确保所有位置满足 WCAG AA 标准。
/* 正例:增加背景色或调整渐变 */
.text-on-gradient {
background:
linear-gradient(to right, rgba(102, 126, 234, 0.9), rgba(118, 75, 162, 0.9)),
#1a1a2e; /* 深色背景兜底 */
color: white;
}
4. 工程实践
4.1 渐变设计令牌
/* design-tokens.css - 渐变设计令牌 */
:root {
/* 主品牌渐变 */
--gradient-brand: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
--gradient-brand-reverse: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
/* 语义渐变 */
--gradient-success: linear-gradient(135deg, #4caf50, #81c784);
--gradient-warning: linear-gradient(135deg, #ff9800, #ffb74d);
--gradient-danger: linear-gradient(135deg, #f44336, #e57373);
--gradient-info: linear-gradient(135deg, #2196f3, #64b5f6);
/* 中性渐变 */
--gradient-neutral: linear-gradient(135deg, #f5f7fa, #c3cfe2);
--gradient-neutral-dark: linear-gradient(135deg, #2c3e50, #4ca1af);
/* 装饰性渐变 */
--gradient-aurora: linear-gradient(
135deg,
#667eea 0%,
#764ba2 25%,
#f093fb 50%,
#f5576c 75%,
#4facfe 100%
);
/* 渐变方向 */
--direction-horizontal: to right;
--direction-vertical: to bottom;
--direction-diagonal: 135deg;
--direction-diagonal-reverse: -45deg;
}
4.2 PostCSS 渐变增强
// postcss.config.js - PostCSS 渐变增强
module.exports = {
plugins: [
require('autoprefixer')({
overrideBrowserslist: ['> 1%', 'last 2 versions'],
}),
// 添加 -webkit- 前缀(background-clip: text)
require('postcss-preset-env')({
stage: 2,
features: {
'is-pseudo-class': true,
},
}),
],
};
4.3 SCSS 渐变 Mixin
// _gradients.scss - SCSS 渐变 Mixin 集合
// 线性渐变
@mixin linear-gradient($direction, $colors...) {
background: linear-gradient($direction, $colors);
}
// 径向渐变
@mixin radial-gradient($shape, $position, $colors...) {
background: radial-gradient($shape at $position, $colors);
}
// 渐变文字
@mixin gradient-text($gradient) {
background: $gradient;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
// 渐变边框
@mixin gradient-border($gradient, $border-width: 2px, $radius: 0) {
border: $border-width solid transparent;
border-radius: $radius;
background:
linear-gradient(white, white) padding-box,
$gradient border-box;
}
// 使用示例
.button {
@include linear-gradient(135deg, #667eea, #764ba2);
}
.title {
@include gradient-text(linear-gradient(to right, #667eea, #764ba2));
}
.card {
@include gradient-border(
linear-gradient(135deg, #667eea, #764ba2),
2px,
8px
);
}
4.4 Tailwind 自定义渐变
// tailwind.config.js - 自定义渐变
module.exports = {
theme: {
extend: {
// 自定义渐变颜色
colors: {
brand: {
start: '#667eea',
end: '#764ba2',
},
},
// 自定义渐变方向
backgroundImage: {
'gradient-brand': 'linear-gradient(135deg, #667eea, #764ba2)',
'gradient-aurora': 'linear-gradient(135deg, #667eea, #764ba2, #f093fb, #f5576c)',
'gradient-mesh': `
radial-gradient(at 0% 0%, rgba(255, 0, 128, 0.5), transparent 50%),
radial-gradient(at 100% 0%, rgba(255, 140, 0, 0.5), transparent 50%),
radial-gradient(at 100% 100%, rgba(138, 43, 226, 0.5), transparent 50%),
radial-gradient(at 0% 100%, rgba(0, 191, 255, 0.5), transparent 50%)
`,
},
// 自定义动画
keyframes: {
'gradient-shift': {
'0%, 100%': { 'background-position': '0% 50%' },
'50%': { 'background-position': '100% 50%' },
},
},
animation: {
'gradient-shift': 'gradient-shift 3s ease infinite',
},
},
},
};
<!-- 使用自定义渐变 -->
<div class="bg-gradient-brand">品牌渐变</div>
<div class="bg-gradient-aurora bg-[length:300%_100%] animate-gradient-shift">
动态极光渐变
</div>
<div class="bg-gradient-mesh">网格渐变</div>
4.5 React 渐变组件
// GradientBackground.tsx - React 渐变组件
import React from 'react';
interface GradientBackgroundProps {
type?: 'linear' | 'radial' | 'conic';
angle?: string;
colors: string[];
colorSpace?: 'srgb' | 'oklab' | 'oklch' | 'lab' | 'lch';
children?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
}
export function GradientBackground({
type = 'linear',
angle = '135deg',
colors,
colorSpace,
children,
className,
style,
}: GradientBackgroundProps) {
const colorList = colors.join(', ');
const interp = colorSpace ? `in ${colorSpace}, ` : '';
let background: string;
if (type === 'linear') {
background = `linear-gradient(${interp}${angle}, ${colorList})`;
} else if (type === 'radial') {
background = `radial-gradient(${interp}circle at center, ${colorList})`;
} else {
background = `conic-gradient(${interp}from ${angle} at 50% 50%, ${colorList})`;
}
return (
<div
className={className}
style={{ background, ...style }}
>
{children}
</div>
);
}
// 使用示例
<GradientBackground
type="linear"
angle="135deg"
colors={['#667eea', '#764ba2']}
colorSpace="oklab"
className="min-h-screen flex items-center justify-center"
>
<h1 className="text-white text-4xl">Hello Gradient</h1>
</GradientBackground>
4.6 渐变性能优化
/* 性能优化技巧 */
/* 1. 使用 will-change 提示浏览器 */
.animated-gradient {
background: linear-gradient(90deg, red, blue);
background-size: 200% 100%;
animation: shift 3s infinite;
will-change: background-position; /* 提示浏览器优化 */
}
/* 2. 避免大尺寸渐变 */
/* 反例:全屏渐变重绘成本高 */
body {
background: linear-gradient(to bottom, #000, #fff);
background-attachment: fixed; /* 固定背景,但移动端性能差 */
}
/* 正例:使用 ::before 伪元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #000, #fff);
z-index: -1;
}
/* 3. 静态渐变避免动画 */
.gradient-static {
background: linear-gradient(135deg, #667eea, #764ba2);
/* 不要对 background 属性本身做动画 */
}
/* 4. 使用 transform 代替 background-position */
.gradient-card {
position: relative;
overflow: hidden;
}
.gradient-card::before {
content: '';
position: absolute;
inset: -50%;
background: linear-gradient(135deg, #667eea, #764ba2);
transition: transform 0.3s;
}
.gradient-card:hover::before {
transform: rotate(180deg);
}
4.7 渐变调试工具
// 渐变调试工具:解析并可视化色标
function parseGradient(gradientStr) {
// 简化的渐变解析(生产环境推荐使用 postcss-value-parser)
const typeMatch = gradientStr.match(/(linear|radial|conic)-gradient/);
const type = typeMatch ? typeMatch[1] : 'linear';
// 提取参数
const innerMatch = gradientStr.match(/gradient\(([^)]+)\)/);
if (!innerMatch) return null;
const parts = innerMatch[1].split(',').map(s => s.trim());
// 解析色标
const stops = parts
.filter(p => p.includes('#') || p.includes('rgb') || p.includes('hsl'))
.map(p => {
const [color, position] = p.split(/\s+/);
return { color, position: position || null };
});
return { type, stops };
}
// 使用示例
const grad = parseGradient('linear-gradient(to right, red 0%, blue 100%)');
console.log(grad);
// { type: 'linear', stops: [{color: 'red', position: '0%'}, {color: 'blue', position: '100%'}] }
4.8 Playwright 视觉回归测试
// gradient.spec.js - Playwright 视觉回归测试
const { test, expect } = require('@playwright/test');
test.describe('渐变视觉回归测试', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000');
});
test('线性渐变正确渲染', async ({ page }) => {
const element = page.locator('.gradient-linear');
await expect(element).toHaveCSS('background-image', /linear-gradient/);
});
test('渐变文字可见', async ({ page }) => {
const element = page.locator('.gradient-text');
// 验证 background-clip
await expect(element).toHaveCSS('-webkit-background-clip', 'text');
await expect(element).toHaveCSS('-webkit-text-fill-color', 'transparent');
});
test('渐变动画运行', async ({ page }) => {
const element = page.locator('.animated-gradient');
// 等待动画运行
await page.waitForTimeout(100);
// 验证 animation 属性
await expect(element).toHaveCSS('animation-name', 'gradient-shift');
});
test('OkLab 插值正确应用', async ({ page }) => {
const element = page.locator('.oklab-gradient');
const bgImage = await element.evaluate(el =>
window.getComputedStyle(el).backgroundImage
);
expect(bgImage).toContain('oklab');
});
});
5. 案例研究
5.1 Bootstrap 5 的渐变实践
Bootstrap 5 提供 bg-gradient 修饰类,将纯色背景转为渐变:
/* Bootstrap 5 源码 */
.bg-gradient {
background-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.15),
rgba(255, 255, 255, 0)
);
}
/* 配合 .bg-primary 使用 */
.bg-primary.bg-gradient {
background-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.15),
rgba(255, 255, 255, 0)
), var(--bs-primary);
}
使用方式:
<div class="bg-primary bg-gradient">渐变背景</div>
特点:渐变效果较微妙(顶部高光),适合按钮与卡片。
5.2 Tailwind CSS v3.4 的渐变实践
Tailwind 提供原子化的渐变工具类:
<!-- 从左到右,蓝到紫 -->
<div class="bg-gradient-to-r from-blue-500 to-purple-500">
渐变背景
</div>
<!-- 三色渐变 -->
<div class="bg-gradient-to-r from-red-500 via-yellow-500 to-green-500">
三色渐变
</div>
<!-- 角度渐变 -->
<div class="bg-gradient-to-br from-pink-500 to-orange-500">
对角渐变
</div>
特点:原子类组合,灵活度高,适合快速原型。
5.3 Material Design 3 的渐变实践
Material Design 3 强调「色彩角色」,渐变用于状态变化:
/* M3 渐变实践 */
.mdc-button--filled {
background: var(--md-sys-color-primary);
/* 微妙的高光渐变 */
background-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.1) 0%,
transparent 100%
);
}
/* 悬停状态:渐变变深 */
.mdc-button--filled:hover {
background-image: linear-gradient(
180deg,
rgba(0, 0, 0, 0.1) 0%,
rgba(0, 0, 0, 0.05) 100%
);
}
5.4 GitHub Primer 的渐变实践
/* Primer 渐变实践 */
.btn-primary {
background-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.15) 0%,
rgba(255, 255, 255, 0) 100%
), #2da44e;
}
/* 渐变边框 */
.gradient-border {
border: 1px solid transparent;
background:
linear-gradient(white, white) padding-box,
linear-gradient(135deg, #667eea, #764ba2) border-box;
}
5.5 Stripe 的渐变美学
Stripe 官网以渐变背景闻名,其核心技术是多层径向渐变叠加:
/* Stripe 风格的网格渐变 */
.hero {
background:
radial-gradient(at 20% 30%, rgba(102, 126, 234, 0.5), transparent 50%),
radial-gradient(at 80% 20%, rgba(118, 75, 162, 0.5), transparent 50%),
radial-gradient(at 50% 80%, rgba(240, 147, 251, 0.5), transparent 50%),
#0a0a1a;
}
5.6 生产事故:渐变导致的 CLS
场景:某电商首页使用大尺寸渐变背景,导致 Cumulative Layout Shift(CLS)评分恶化。
根因:
- 渐变通过
background-attachment: fixed实现,移动端滚动时重绘成本高。 - 渐变叠加在图片上,图片加载完成后渐变位置偏移。
- 渐变动画导致持续重绘。
解决方案:
- 移除
background-attachment: fixed,改用position: fixed伪元素。 - 为图片容器预留固定尺寸(
aspect-ratio)。 - 静态渐变替代动画渐变,或使用
will-change提示。
/* 修复后 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #667eea, #764ba2);
z-index: -1;
}
.image-container {
aspect-ratio: 16 / 9; /* 预留尺寸 */
}
填空题知识点讲解
题目 1:linear-gradient 的默认方向是 ________。
解析讲解:to bottom(从上到下)
解析讲解:未指定方向时,linear-gradient 默认从上到下,即 to bottom,对应角度 180deg。
题目 2:repeating-linear-gradient 的周期由 ________ 决定。
解析讲解:最后一个色标的位置
解析讲解:repeating-linear-gradient 将色标位置模「最后一个色标位置」,形成周期性渐变。例如 repeating-linear-gradient(45deg, red 0px, blue 20px) 的周期为 20px。
题目 3:CSS Images Level 4 中,in oklch longer hue 表示 ________。
解析讲解:在 OkLCH 色彩空间中,色相取较长弧插值
解析讲解:longer hue 关键字指定色相插值取较长弧(>180°),适用于需要经过完整色相轮的渐变。
题目 4:background-clip: text 需要配合 ________ 属性使文字颜色透明,以显示背景渐变。
解析讲解:-webkit-text-fill-color: transparent(或 color: transparent)
解析讲解:background-clip: text 将背景裁剪到文字区域,但文字本身的颜色仍会覆盖背景。需通过 -webkit-text-fill-color: transparent(WebKit 前缀)或 color: transparent 使文字颜色透明。
题目 5:conic-gradient 的起始角度(12 点方向)可通过 ________ 关键字调整。
解析讲解:from <angle>
解析讲解:conic-gradient(from 45deg, ...) 表示从 45° 开始(顺时针),用于调整起始位置,常用于隐藏接缝。
编程题知识点讲解
题目 1:使用 conic-gradient 实现一个 75% 完成的进度环,带中心镂空与百分比文字。
解析讲解:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>进度环</title>
<style>
.progress-ring {
position: relative;
width: 200px;
height: 200px;
border-radius: 50%;
/* 75% 完成 */
background: conic-gradient(
#4caf50 0% 75%,
#e0e0e0 75% 100%
);
}
/* 中心镂空 */
.progress-ring::before {
content: '';
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
background: white;
border-radius: 50%;
}
/* 百分比文字 */
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 28px;
font-weight: bold;
color: #4caf50;
z-index: 1;
}
</style>
</head>
<body>
<div class="progress-ring">
<span class="progress-text">75%</span>
</div>
</body>
</html>
解析讲解:
conic-gradient实现 75% 绿色 + 25% 灰色。::before伪元素实现中心镂空。- 绝对定位的
<span>显示百分比。
题目 2:使用 repeating-linear-gradient 实现棋盘格纹理。
解析讲解:
.checkerboard {
width: 300px;
height: 300px;
/* 两层渐变叠加实现棋盘格 */
background:
repeating-linear-gradient(0deg, transparent 0, transparent 40px, #000 40px, #000 80px),
repeating-linear-gradient(90deg, transparent 0, transparent 40px, #000 40px, #000 80px);
background-color: #fff;
}
解析讲解:
- 第一层:水平条纹(0deg),每 40px 交替。
- 第二层:垂直条纹(90deg),每 40px 交替。
- 两层叠加形成棋盘格。
background-color: #fff提供底色。
题目 3:编写 JavaScript 函数,生成随机彩虹渐变字符串。
解析讲解:
/**
* 生成随机彩虹渐变
* @param {number} stops - 色标数量
* @returns {string} linear-gradient 字符串
*/
function generateRainbowGradient(stops = 5) {
const colors = [];
for (let i = 0; i < stops; i++) {
// 在 HSL 色相轮上均匀分布
const hue = Math.round((360 / stops) * i);
const saturation = 70 + Math.random() * 30; // 70-100%
const lightness = 50 + Math.random() * 20; // 50-70%
colors.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`);
}
// 首尾相同,避免接缝(适用于 conic-gradient)
colors.push(colors[0]);
return `linear-gradient(in oklch longer hue, ${colors.join(', ')})`;
}
// 使用示例
document.body.style.background = generateRainbowGradient(6);
解析讲解:
- 在 HSL 色相轮上均匀分布色标。
- 随机化饱和度与亮度,增加多样性。
- 使用
oklch longer hue插值,确保色相完整过渡。 - 首尾颜色相同,适用于
conic-gradient。
10.1 W3C 规范
- World Wide Web Consortium. (2019). CSS Images Module Level 3. W3C Candidate Recommendation. https://www.w3.org/TR/css-images-3/
- World Wide Web Consortium. (2024). CSS Images Module Level 4. W3C Working Draft. https://www.w3.org/TR/css-images-4/
- World Wide Web Consortium. (2023). CSS Color Module Level 4. W3C Candidate Recommendation. https://www.w3.org/TR/css-color-4/
- World Wide Web Consortium. (2024). CSS Color Module Level 5. W3C Working Draft. https://www.w3.org/TR/css-color-5/
- World Wide Web Consortium. (2022). CSS Houdini: Properties and Values API Level 1. W3C Working Draft. https://www.w3.org/TR/css-properties-values-api-1/
10.2 学术论文
- Björn Ottosson. (2020). A perceptual color space for image processing. https://bottosson.github.io/posts/oklab/
- Smith, A. R. (1978). Color gamut transform pairs. ACM SIGGRAPH Computer Graphics, 12(3), 12-19. DOI: 10.1145/965139.807361
- Poynton, C. (2012). Digital Video and HD: Algorithms and Interfaces (2nd ed.). Morgan Kaufmann. ISBN: 978-0123919267.
- Sharma, G., & Trussell, H. J. (1997). Digital color imaging. IEEE Transactions on Image Processing, 6(7), 901-932. DOI: 10.1109/83.597278
10.3 工业实践
- Bootstrap. (2024). Bootstrap 5.4 Documentation: Background Gradient. https://getbootstrap.com/docs/5.4/utilities/background/
- Tailwind Labs. (2024). Tailwind CSS v3.4 Documentation: Background Image. https://tailwindcss.com/docs/background-image
- Google. (2024). Material Design 3: Color Roles. https://m3.material.io/styles/color/roles
- GitHub. (2024). Primer Design System: Color. https://primer.style/foundations/color
10.4 工具与库
- CSSGradient.io. (2024). Free CSS Gradient Generator. https://cssgradient.io/
- Verou, L. (2024). CSS3 Test: Conic Gradients. https://leaverou.github.io/conic-gradient/
- Khan, A. (2024). Gradienta: Free CSS Gradient Generator. https://gradienta.io/
10.5 ACM Reference Format
- World Wide Web Consortium. 2019. CSS Images Module Level 3. W3C Candidate Recommendation. Retrieved July 20, 2026 from https://www.w3.org/TR/css-images-3/
- Tab Atkins, and Elika Etemad. 2024. CSS Images Module Level 4. W3C Working Draft. Retrieved July 20, 2026 from https://www.w3.org/TR/css-images-4/
- Björn Ottosson. 2020. A perceptual color space for image processing. Retrieved July 20, 2026 from https://bottosson.github.io/posts/oklab/
- Alvy Ray Smith. 1978. Color gamut transform pairs. In Proceedings of the 5th annual conference on Computer graphics and interactive techniques (SIGGRAPH ‘78). Association for Computing Machinery, New York, NY, USA, 12-19. DOI: https://doi.org/10.1145/965139.807361
- Charles Poynton. 2012. Digital Video and HD: Algorithms and Interfaces (2nd ed.). Morgan Kaufmann, Burlington, MA. ISBN 978-0123919267.
11.1 经典书籍
- 《CSS Secrets》 - Lea Verou 著,深入探讨渐变与色彩的高级技巧。
- 《Designing Web Interfaces》 - Bill Scott 著,渐变在 UI 设计中的应用。
- 《Color and Light in Nature and Art》 - Samuel J. Williamson 著,色彩理论。
- 《Interaction of Color》 - Josef Albers 著,色彩交互经典。
11.3 视频课程
- Frontend Masters: CSS Grid & Flexbox for Responsive Layouts - Jen Kramer
- Lea Verou: CSS Gradients Deep Dive - CSSConf 演讲
- Una Kravets: CSS Color Spaces - Chrome Developers
11.4 社区博客
- CSS-Tricks - https://css-tricks.com/
- Smashing Magazine - https://www.smashingmagazine.com/category/css/
- Lea Verou’s Blog - https://lea.verou.me/
- Björn Ottosson’s Blog - https://bottosson.github.io/
11.5 规范演进方向
- CSS Images Level 5 草案:探讨
mesh-gradient(网格渐变)与spline-gradient(样条插值)。 - CSS Easing Functions Level 2:渐变色标间的缓动函数。
- CSS Houdini Paint API:自定义渐变绘制,突破规范限制。
- HDR 渐变:支持 10-bit / 12-bit 色深与广色域。
11.6 相关规范
- CSS Backgrounds and Borders Module Level 3 - 背景与边框规范。
- CSS Color Module Level 4 - 色彩规范。
- CSS Values and Units Module Level 4 - 值与单位规范。
- SVG 2: Gradients and Patterns - SVG 渐变规范。
6. 深入理解(选读)
以下内容适合想彻底搞懂机制原理的读者,第一遍学习可跳过。
6.1 历史演进
6.1.1 CSS 3(2012):渐变的诞生
CSS 渐变最初由 Apple 于 2008 年在 WebKit 中以 -webkit-gradient(linear, ...) 形式实现,语法较为复杂。2012 年,CSS Images Module Level 3 将其标准化为现代语法:
background: linear-gradient(to right, red, blue);
background: radial-gradient(circle at center, red, blue);
CSS 3 渐变的核心贡献:
- 无需图片资源:渐变作为 CSS 值,无需 HTTP 请求,提升性能。
- 可缩放:矢量特性,任意尺寸下保持清晰。
- 可动画:通过
background-position或 CSS Houdini 实现渐变动画(虽有限制)。
6.1.2 conic-gradient 的引入(2017)
conic-gradient(锥形渐变)由 Lea Verou 提议,2017 年在 Chrome 69 与 Safari 12.1 中实现。它填补了 CSS 渐变在「角度方向」上的空白:
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
锥形渐变的典型应用:饼图、色轮、进度环。
6.1.3 CSS Images Module Level 4(2020-2024)
CSS Images Module Level 4 引入了多项重要改进:
- 色彩空间插值:
in oklab、in srgb等关键字,允许指定插值色彩空间。 - 双色标语法:
red 25% 50%表示红色从 25% 持续到 50%(硬边界)。 interpolar关键字:精细控制色相插值(shorter、longer、increasing、decreasing)。
/* Level 4 新语法 */
background: linear-gradient(in oklab, red, blue);
background: linear-gradient(in oklch longer hue, red, blue);
background: linear-gradient(red 25%, blue 50% 75%, green);
6.1.4 色彩空间的演进
| 年份 | 事件 | 核心变化 |
|---|---|---|
| 2008 | WebKit 首次实现渐变 | -webkit-gradient(linear, ...) 语法 |
| 2012 | CSS Images Level 3 推荐 | linear-gradient / radial-gradient 标准化 |
| 2017 | conic-gradient 浏览器支持 | 锥形渐变落地 |
| 2020 | CSS Color Level 4 草案 | 引入 oklab / oklch 色彩空间 |
| 2022 | CSS Images Level 4 草案 | in oklab 插值语法 |
| 2023 | lab() / lch() / oklab() 浏览器支持 | 现代色彩空间普及 |
| 2024 | Display P3 与 Rec2020 支持 | 广色域渐变 |
6.1.5 演进时间线
| 年份 | 规范/事件 | 核心变化 |
|---|---|---|
| 2008 | WebKit 渐变实现 | 私有语法 |
| 2012 | CSS Images Level 3 | linear-gradient / radial-gradient 标准化 |
| 2017 | conic-gradient | 锥形渐变(Chrome 69+, Safari 12.1+) |
| 2019 | 双色标语法 | red 25% 50% 硬边界 |
| 2020 | in oklab 插值 | Lab/LCH 色彩空间插值 |
| 2022 | CSS Images Level 4 草案 | 完整的插值控制语法 |
| 2023 | color-mix() 函数 | 渐变色标动态混合 |
| 2024 | Display P3 渐变 | 广色域支持 |
6.2 形式化定义
6.2.1 规范条款
依据 CSS Images Module Level 3 §4:
A gradient is an image that smoothly transitions from one color to another. CSS defines three types of gradients: linear, radial, and conic.
以及 CSS Images Module Level 4 §4.1:
If the first argument to a linear gradient is the keyword
in, the next keyword specifies the color space used for interpolation.
6.2.2 核心术语
| 术语 | 英文 | 定义 |
|---|---|---|
| 渐变 | Gradient | 平滑过渡的图像 |
| 梯度线 | Gradient Line | 线性渐变的方向轴 |
| 渐变射线 | Gradient Ray | 径向渐变的中心射线 |
| 渐变弧 | Gradient Arc | 锥形渐变的角度弧 |
| 色标 | Color Stop | 渐变中的颜色锚点 |
| 色标位置 | Color Stop Position | 色标在渐变中的位置(百分比或长度) |
| 插值 | Interpolation | 两色标之间的颜色过渡 |
| 硬边界 | Hard Stop | 两色标位置相同,形成清晰边界 |
| 色带效应 | Banding | 渐变中的颜色断层 |
6.2.3 linear-gradient 语法
linear-gradient() =
linear-gradient(
[ [ <angle> | to <side-or-corner> ] || in <color-space> [ longer | shorter | increasing | decreasing ] hue? ]?,
<color-stop-list>
)
<side-or-corner> = [left | right] || [top | bottom]
<color-stop-list> = <color-stop>#{2,}
<color-stop> = <color> <length-percentage>?{1,2}
6.2.4 radial-gradient 语法
radial-gradient() =
radial-gradient(
[ [ <ending-shape> || <size> ] [ at <position> ]? ]?,
<color-stop-list>
)
<ending-shape> = circle | ellipse
<size> =
closest-side | farthest-side |
closest-corner | farthest-corner |
<length> | <length-percentage>{2}
6.2.5 conic-gradient 语法
conic-gradient() =
conic-gradient(
[ [ from <angle> ]? [ at <position> ]? ] || in <color-space>,
<color-stop-list>
)
6.2.6 形式化定义:梯度线
设 linear-gradient 的方向为 (从上至下为 ,顺时针增加),容器尺寸为 。梯度线的长度 定义为:
梯度线的起点与终点位于容器的对角线上,方向由 决定。色标 在位置 处,颜色由线性插值得到:
其中 。
6.2.7 形式化定义:径向渐变
设径向渐变的中心为 ,形状为 circle 或 ellipse,尺寸由关键字决定:
closest-side:到最近边的距离。farthest-side:到最远边的距离。closest-corner:到最近角的距离。farthest-corner(默认):到最远角的距离。
对于 circle 形状,渐变半径 定义为:
6.2.8 形式化定义:锥形渐变
锥形渐变的颜色由角度 决定(从 12 点方向开始,顺时针):
其中 。若首尾色标颜色不同,渐变在 处形成「接缝」。
6.2.9 颜色插值
CSS Images Level 4 支持的色彩空间:
| 色彩空间 | 语法 | 特性 |
|---|---|---|
srgb | in srgb | 默认,sRGB 线性插值 |
linearRGB | in linearRGB | 线性 RGB 空间,物理准确 |
lab | in lab | CIE Lab 空间,感知均匀 |
lch | in lch | CIE LCH 空间,色相旋转 |
oklab | in oklab | Oklab 空间(2020),改进 Lab |
oklch | in oklch | OkLCH 空间,现代首选 |
hsl | in hsl | HSL 空间,色相插值 |
hwb | in hwb | HWB 空间 |
xyz | in xyz | CIE XYZ 空间 |
色相插值方式(仅 lch、oklch、hsl、hwb):
shorter hue(默认):取较短弧。longer hue:取较长弧。increasing hue:递增方向。decreasing hue:递减方向。
6.2.10 色标位置规则
色标位置的规范化规则:
- 若首色标未指定位置,默认为
0%。 - 若末色标未指定位置,默认为
100%。 - 若中间色标位置小于前一个,自动调整为前一个的位置。
- 双色标语法
red 25% 50%等价于red 25%, red 50%,形成硬边界。
形式化地,设色标序列为 ,规范化函数:
6.3 理论推导与原理解析
6.3.1 梯度线的几何推导
给定容器尺寸 与方向角 (从上至下为 ,顺时针),梯度线的方向向量为:
梯度线垂直于方向向量的「梯度线长度」 通过容器的对角线投影得到:
证明:设梯度线方向为 ,其垂直方向为 。容器的四个角在 方向上的投影差即为梯度线长度:
展开后得到 。
6.3.2 颜色插值的数学模型
给定两色标 与 ,插值参数 。
sRGB 线性插值(默认):
linearRGB 插值:
先进行 gamma 解码(sRGB → linear),插值后再编码(linear → sRGB):
Oklab 插值:
转换到 Oklab 空间,插值,再转换回 sRGB:
Oklab 空间的优势在于感知均匀性:相同数值差对应相同感知色差,因此渐变更平滑。
6.3.3 色相插值的歧义
在 HSL / LCH / OkLCH 空间中,色相是角度,两色相之间存在两种插值路径:
- 较短弧(
shorter,默认):取角度差 的方向。 - 较长弧(
longer):取角度差 的方向。
设两色相为 与 (角度,),较短弧的角度差:
例如,从红色()到蓝色():
- 较短弧:,取 ,即逆时针 ,经过品红。
- 较长弧:,顺时针 ,经过黄、绿、青。
6.3.4 色带效应(Banding)的成因
色带效应是渐变中颜色断层现象,成因包括:
- 8-bit 量化:每个通道仅 256 级,长渐变中相邻像素色差小于 1 级时无法区分。
- sRGB 非线性:sRGB 空间的线性插值在感知上不均匀,暗部细节丢失。
- 显示器精度:8-bit 显示器无法呈现更细的色差。
缓解方案:
- 使用
oklab插值:感知均匀,减少暗部断层。 - 添加微噪声:通过 SVG 噪声或
background-image叠加细小纹理,打破色带。 - 使用更高位深:10-bit / 12-bit 显示器与 HDR 内容。
/* 方案 1:oklab 插值 */
background: linear-gradient(in oklab, #000, #fff);
/* 方案 2:叠加噪声 */
background:
url('noise.svg'),
linear-gradient(to right, #000, #fff);
6.3.5 硬边界的几何特性
硬边界(Hard Stop)是两色标位置相同的情况,形成清晰的颜色分界:
background: linear-gradient(to right, red 50%, blue 50%);
数学上,硬边界处的颜色不连续:
硬边界常用于:
- 条纹纹理(配合
repeating-linear-gradient)。 - 分块布局(如双栏分色)。
- 进度条(已完成 vs 未完成)。
6.3.6 repeating-linear-gradient 的周期性
repeating-linear-gradient 将色标位置模 (梯度线长度),形成周期性渐变:
background: repeating-linear-gradient(
45deg,
#fff 0px,
#fff 10px,
#000 10px,
#000 20px
);
数学上,周期 ,颜色函数:
其中 是基础渐变( 范围内)。
6.3.7 conic-gradient 的接缝问题
conic-gradient 在 与 处可能形成「接缝」:
background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
若首尾色标颜色相同(如上例的 red),接缝不可见。若不同,则形成硬边界。
解决方案:
- 首尾使用相同颜色。
- 使用
from <angle>调整起始角度,将接缝隐藏在不可见区域。 - 通过
mask遮挡接缝。
6.3.8 渐变与可访问性
渐变对可访问性的影响:
- 对比度:渐变背景上的文字对比度随位置变化,需确保所有位置满足 WCAG AA 标准(4.5:1)。
- 色盲友好:避免仅依赖色相差异传递信息,应配合明度或图案。
prefers-contrast:用户偏好高对比度时,应简化或移除渐变。
@media (prefers-contrast: more) {
.button {
background: solid-color; /* 移除渐变 */
}
}
7. 本章综合挑战(选做)
- 用
linear-gradient做一张“红黄蓝”三色过渡的背景,再用角度 45deg 重做一次; - 用
repeating-linear-gradient做条纹纹理,并调整色标位置改变条纹宽度; - 用
radial-gradient做光晕效果,用conic-gradient做简易饼图; - 用
background-clip: text实现渐变文字,注意兼容性处理。
8. 核心知识点
一句话记住渐变:
linear直线过渡、radial向外扩散、conic绕圈过渡;repeating-*可重复,色标定位置,background-clip: text做渐变文字。
linear-gradient(方向, 色标...):直线渐变,方向可用角度或关键词;radial-gradient(形状, 色标...):从中心向外扩散;conic-gradient:绕圆心一圈过渡,适合饼图与色轮;repeating-linear/radial-gradient:重复图案(条纹、网格);- 色标位置用百分比或长度控制,相同位置形成硬边界;
- 渐变是
background-image的取值,可与背景色叠加; - 渐变文字:
background-clip: text+color: transparent。
9. 注意事项与改进建议
| 问题点 | 说明 | 改进方案 |
|---|---|---|
| 色带效应 | 色标过少出现明显分带 | 增加中间色标或用 oklab 插值 |
| 硬边界滥用 | 视觉突兀 | 只在条纹/分隔场景使用 |
background-clip: text 兼容 | 旧浏览器不支持 | 提供纯色兜底 |
| 方向歧义 | to right 与 45deg 混用 | 统一使用角度或关键词 |
| 渐变动画性能 | 大面积渐变重绘开销大 | 缩小渐变区域或用合成层 |
| 对比度不足 | 渐变文字可读性差 | 保证文字与背景对比度 |
10. 扩展学习
- 背景体系:
css/290-BackgroundEnhancement; - 颜色与插值:
css/400-ModernColorSpace(oklab/oklch); - 动画:
css/330-CSSAnimationTransition中渐变动画; - 实战:
css/680-CSSProjectExampleResponsiveHomepage的渐变应用。
附录 A:术语表
| 术语 | 英文 | 定义 |
|---|---|---|
| 渐变 | Gradient | 平滑过渡的图像 |
| 梯度线 | Gradient Line | 线性渐变的方向轴 |
| 渐变射线 | Gradient Ray | 径向渐变的中心射线 |
| 渐变弧 | Gradient Arc | 锥形渐变的角度弧 |
| 色标 | Color Stop | 渐变中的颜色锚点 |
| 色标位置 | Color Stop Position | 色标在渐变中的位置 |
| 插值 | Interpolation | 两色标之间的颜色过渡 |
| 硬边界 | Hard Stop | 两色标位置相同 |
| 色带效应 | Banding | 渐变中的颜色断层 |
| 色彩空间 | Color Space | 颜色表示的数学模型 |
| OkLab | OkLab | 感知均匀的色彩空间(2020) |
| OkLCH | OkLCH | OkLab 的极坐标形式 |
附录 B:浏览器兼容性
| 特性 | Chrome | Firefox | Safari | Edge | 兼容性 |
|---|---|---|---|---|---|
linear-gradient | 全部 | 全部 | 全部 | 全部 | 100% |
radial-gradient | 全部 | 全部 | 全部 | 全部 | 100% |
conic-gradient | 69+ | 83+ | 12.1+ | 79+ | 95%+ |
repeating-* | 全部 | 全部 | 全部 | 全部 | 100% |
双色标语法 red 25% 50% | 89+ | 83+ | 15+ | 89+ | 90%+ |
in oklab 插值 | 111+ | 113+ | 16.2+ | 111+ | 80%+ |
in oklch 插值 | 111+ | 113+ | 16.2+ | 111+ | 80%+ |
@property 动画 | 85+ | 128+ | 16.4+ | 85+ | 70%+ |
background-clip: text | 全部(-webkit-) | 49+ | 全部(-webkit-) | 全部 | 95%+ |
附录 C:调试检查清单
- 使用 DevTools 检查渐变背景的
background-image值 - 验证色标位置是否符合预期
- 检查
conic-gradient的接缝是否隐藏 - 验证渐变文字的对比度满足 WCAG AA 标准
- 检查渐变动画的性能(避免
background-position动画) - 测试跨浏览器兼容性(特别是
oklab插值) - 验证
prefers-reduced-motion下渐变动画是否暂停 - 检查
prefers-contrast: more下渐变是否简化 - 使用 Lighthouse 检查 CLS(Cumulative Layout Shift)
- 编写 Playwright 视觉回归测试
linear-gradient 线性渐变
基本写法:两色线性渐变
background: linear-gradient(<方向>, <颜色1>, <颜色2>);
/* 两色线性渐变 */
.header {
background: linear-gradient(135deg, #007bff, #0056b3);
}
基本写法:三色线性渐变
background: linear-gradient(<方向>, <颜色1>, <颜色2>, <颜色3>);
/* 三色线性渐变 */
.rainbow {
background: linear-gradient(90deg, red, yellow, green);
}
基本写法:to 方向渐变
background: linear-gradient(to <方向>, <颜色1>, <颜色2>);
/* 使用 to 关键字指定方向 */
.header {
background: linear-gradient(to right, #007bff, #0056b3);
}
基本写法:to 双方向渐变
background: linear-gradient(to <方向1> <方向2>, <颜色1>, <颜色2>);
/* 指定对角方向 */
.header {
background: linear-gradient(to bottom right, #007bff, #0056b3);
}
基本写法:角度渐变
background: linear-gradient(<角度>, <颜色1>, <颜色2>);
/* 使用角度指定方向 */
.header {
background: linear-gradient(45deg, #007bff, #0056b3);
}
基本写法:带位置渐变
background: linear-gradient(<方向>, <颜色1> <位置1>, <颜色2> <位置2>);
/* 指定颜色位置 */
.header {
background: linear-gradient(90deg, #007bff 0%, #0056b3 100%);
}
单行写法:多色多位置渐变
background: linear-gradient(<方向>, <颜色1> <位置1>, <颜色2> <位置2>, <颜色3> <位置3>);
/* 单行多色多位置渐变 */
.header {
background: linear-gradient(90deg, #007bff 0%, #0056b3 50%, #003d7a 100%);
}
换行写法:多色多位置渐变
background: linear-gradient(<方向>, <颜色1> <位置1>, <颜色2> <位置2>, <颜色3> <位置3>);
/* 换行多色多位置渐变 */
.header {
background: linear-gradient(
90deg,
#007bff 0%,
#0056b3 50%,
#003d7a 100%
);
}
基本写法:硬边渐变
background: linear-gradient(<方向>, <颜色1> <位置>, <颜色2> <位置>);
/* 创建硬边过渡 */
.stripe {
background: linear-gradient(90deg, #007bff 50%, #0056b3 50%);
}
radial-gradient 径向渐变
基本写法:圆形径向渐变
background: radial-gradient(circle, <颜色1>, <颜色2>);
/* 圆形径向渐变 */
.radial {
background: radial-gradient(circle, #007bff, #0056b3);
}
基本写法:椭圆径向渐变
background: radial-gradient(ellipse, <颜色1>, <颜色2>);
/* 椭圆径向渐变 */
.radial {
background: radial-gradient(ellipse, #007bff, #0056b3);
}
基本写法:带位置径向渐变
background: radial-gradient(circle at <位置>, <颜色1>, <颜色2>);
/* 指定圆心位置 */
.radial {
background: radial-gradient(circle at top left, #007bff, #0056b3);
}
基本写法:带尺寸径向渐变
background: radial-gradient(<尺寸> circle, <颜色1>, <颜色2>);
/* 指定圆尺寸 */
.radial {
background: radial-gradient(100px circle, #007bff, #0056b3);
}
基本写法:closest-side
background: radial-gradient(closest-side, <颜色1>, <颜色2>);
/* 渐变到最近的边 */
.radial {
background: radial-gradient(closest-side, #007bff, #0056b3);
}
基本写法:farthest-corner
background: radial-gradient(farthest-corner, <颜色1>, <颜色2>);
/* 渐变到最远的角 */
.radial {
background: radial-gradient(farthest-corner, #007bff, #0056b3);
}
基本写法:带颜色位置径向渐变
background: radial-gradient(circle, <颜色1> <位置1>, <颜色2> <位置2>);
/* 指定颜色位置 */
.radial {
background: radial-gradient(circle, #007bff 0%, #0056b3 100%);
}
conic-gradient 圆锥渐变
基本写法:圆锥渐变
background: conic-gradient(<颜色1>, <颜色2>, <颜色1>);
/* 圆锥渐变 */
.conic {
background: conic-gradient(red, yellow, green, red);
}
基本写法:带角度圆锥渐变
background: conic-gradient(from <角度>, <颜色1>, <颜色2>);
/* 指定起始角度 */
.conic {
background: conic-gradient(from 0deg, red, yellow, green, red);
}
基本写法:带位置圆锥渐变
background: conic-gradient(from <角度> at <位置>, <颜色1>, <颜色2>);
/* 指定起始角度和位置 */
.conic {
background: conic-gradient(from 0deg at center, red, yellow, green, red);
}
基本写法:硬边圆锥渐变
background: conic-gradient(<颜色1> <角度1>, <颜色2> <角度2>);
/* 创建饼图效果 */
.pie {
background: conic-gradient(red 0deg 90deg, blue 90deg 360deg);
}
repeating-linear-gradient 重复线性渐变
基本写法:重复线性渐变
background: repeating-linear-gradient(<方向>, <颜色1>, <颜色2> <宽度>);
/* 重复线性渐变 */
.stripes {
background: repeating-linear-gradient(45deg, #007bff, #007bff 10px, #0056b3 10px, #0056b3 20px);
}
基本写法:水平条纹
background: repeating-linear-gradient(<方向>, <颜色1> <宽度>, <颜色2> <宽度>);
/* 水平条纹背景 */
.stripes {
background: repeating-linear-gradient(0deg, #007bff 0, #007bff 10px, #0056b3 10px, #0056b3 20px);
}
基本写法:垂直条纹
background: repeating-linear-gradient(<方向>, <颜色1> <宽度>, <颜色2> <宽度>);
/* 垂直条纹背景 */
.stripes {
background: repeating-linear-gradient(90deg, #007bff 0, #007bff 10px, #0056b3 10px, #0056b3 20px);
}
repeating-radial-gradient 重复径向渐变
基本写法:重复径向渐变
background: repeating-radial-gradient(circle, <颜色1>, <颜色2> <宽度>);
/* 重复径向渐变 */
.rings {
background: repeating-radial-gradient(circle, #007bff 0, #007bff 10px, #0056b3 10px, #0056b3 20px);
}
基本写法:同心圆
background: repeating-radial-gradient(<颜色1> <宽度>, <颜色2> <宽度>);
/* 同心圆效果 */
.rings {
background: repeating-radial-gradient(circle at center, #007bff 0, #007bff 5px, transparent 5px, transparent 10px);
}
多重渐变
单行写法:多重渐变
background: <渐变1>, <渐变2>;
/* 单行设置多重渐变 */
.box {
background: linear-gradient(135deg, transparent, rgba(0,0,0,0.5)), radial-gradient(circle, #007bff, #0056b3);
}
换行写法:多重渐变
background: <渐变1>, <渐变2>, <渐变3>;
/* 换行设置多重渐变 */
.box {
background:
linear-gradient(135deg, transparent, rgba(0,0,0,0.5)),
radial-gradient(circle, #007bff, #0056b3),
url("texture.png");
}
渐变与变量
基本写法:使用变量定义渐变
:root { --gradient-<名>: <渐变值>; }
/* 定义渐变变量 */
:root {
--gradient-primary: linear-gradient(135deg, #007bff, #0056b3);
--gradient-secondary: linear-gradient(135deg, #6c757d, #495057);
}
基本写法:使用渐变变量
background: var(--gradient-<名>);
/* 使用渐变变量 */
.header {
background: var(--gradient-primary);
}
基本写法:变量在渐变中使用
background: linear-gradient(<方向>, var(--<颜色1>), var(--<颜色2>));
/* 在渐变中使用颜色变量 */
.header {
background: linear-gradient(135deg, var(--color-start), var(--color-end));
}
渐变方向
基本写法:to top 向上
background: linear-gradient(to top, <颜色1>, <颜色2>);
/* 向上的渐变 */
.box {
background: linear-gradient(to top, #007bff, #0056b3);
}
基本写法:to bottom 向下
background: linear-gradient(to bottom, <颜色1>, <颜色2>);
/* 向下的渐变 */
.box {
background: linear-gradient(to bottom, #007bff, #0056b3);
}
基本写法:to left 向左
background: linear-gradient(to left, <颜色1>, <颜色2>);
/* 向左的渐变 */
.box {
background: linear-gradient(to left, #007bff, #0056b3);
}
基本写法:to right 向右
background: linear-gradient(to right, <颜色1>, <颜色2>);
/* 向右的渐变 */
.box {
background: linear-gradient(to right, #007bff, #0056b3);
}
透明度渐变
基本写法:透明渐变
background: linear-gradient(<方向>, transparent, <颜色>);
/* 从透明到不透明 */
.fade {
background: linear-gradient(to bottom, transparent, #000000);
}
基本写法:半透明渐变
background: linear-gradient(<方向>, rgba(<颜色>, <透明度1>), rgba(<颜色>, <透明度2>));
/* 半透明渐变 */
.overlay {
background: linear-gradient(135deg, rgba(0,123,255,0.8), rgba(0,86,179,0.6));
}
基本写法:淡出效果
background: linear-gradient(<方向>, <颜色>, transparent);
/* 从不透明到透明 */
.fade-out {
background: linear-gradient(to bottom, #007bff, transparent);
}
渐变动画
基本写法:渐变过渡
background-size: <尺寸>; transition: background-position <时长>;
/* 渐变背景过渡动画 */
.animated {
background: linear-gradient(90deg, #007bff, #0056b3, #007bff);
background-size: 200% 100%;
transition: background-position 0.5s;
}
.animated:hover {
background-position: 100% 0;
}
基本写法:渐变流动动画
@keyframes <名称> { from { background-position: 0% 0%; } to { background-position: 100% 0%; } }
/* 渐变流动动画 */
@keyframes gradientFlow {
from { background-position: 0% 0%; }
to { background-position: 100% 0%; }
}
.flowing {
background: linear-gradient(90deg, #007bff, #0056b3, #007bff);
background-size: 200% 100%;
animation: gradientFlow 3s linear infinite;
}
常见渐变效果
基本写法:按钮渐变
background: linear-gradient(<方向>, <颜色1>, <颜色2>);
/* 按钮渐变背景 */
.btn {
background: linear-gradient(135deg, #007bff, #0056b3);
}
基本写法:卡片渐变
background: linear-gradient(<方向>, <颜色1>, <颜色2>);
/* 卡片渐变背景 */
.card {
background: linear-gradient(135deg, #f8f9fa, #e9ecef);
}
基本写法:遮罩渐变
background: linear-gradient(<方向>, transparent, <颜色>);
/* 底部遮罩渐变 */
.overlay {
background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
}
基本写法:网格背景
background: linear-gradient(<方向1>, <颜色> <宽度>, transparent <宽度>), linear-gradient(<方向2>, <颜色> <宽度>, transparent <宽度>);
/* 网格背景 */
.grid-bg {
background:
linear-gradient(90deg, #ccc 1px, transparent 1px),
linear-gradient(0deg, #ccc 1px, transparent 1px);
background-size: 20px 20px;
}
基本写法:对角条纹
background: repeating-linear-gradient(45deg, <颜色1> <宽度>, <颜色2> <宽度>);
/* 对角条纹背景 */
.diagonal-stripes {
background: repeating-linear-gradient(45deg, #007bff 0, #007bff 10px, #0056b3 10px, #0056b3 20px);
}
基本写法:棋盘格背景
background: conic-gradient(<颜色1> <角度>, <颜色2> <角度>, <颜色1> <角度>, <颜色2> <角度>);
/* 棋盘格背景 */
.checkerboard {
background: conic-gradient(#000 0deg 90deg, #fff 90deg 180deg, #000 180deg 270deg, #fff 270deg 360deg);
background-size: 50px 50px;
}
渐变文本
基本写法:渐变文字
background: linear-gradient(<方向>, <颜色1>, <颜色2>); -webkit-background-clip: text; color: transparent;
/* 渐变文字效果 */
.gradient-text {
background: linear-gradient(135deg, #007bff, #0056b3);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
基本写法:多色渐变文字
background: linear-gradient(<方向>, <颜色1>, <颜色2>, <颜色3>); -webkit-background-clip: text; color: transparent;
/* 多色渐变文字 */
.rainbow-text {
background: linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
响应式渐变
基本写法:clamp 响应式渐变
background: linear-gradient(<角度>, <颜色1>, <颜色2>)
/* 响应式渐变角度 */
.box {
background: linear-gradient(clamp(45deg, 10vw, 135deg), #007bff, #0056b3);
}
基本写法:媒体查询调整渐变
@media (max-width: <值>) { background: <渐变>; }
/* 小屏幕调整渐变 */
.box {
background: linear-gradient(135deg, #007bff, #0056b3);
}
@media (max-width: 768px) {
.box {
background: linear-gradient(180deg, #007bff, #0056b3);
}
}
基本写法:嵌套媒体查询渐变
.box { background: <渐变>; @media (max-width: <值>) { background: <渐变>; } }
/* CSS 原生嵌套媒体查询渐变 */
.box {
background: linear-gradient(135deg, #007bff, #0056b3);
@media (max-width: 768px) {
background: linear-gradient(180deg, #007bff, #0056b3);
}
}