4.5 渐变与阴影
渐变(Gradients)和阴影(Shadows)是创建视觉深度和层次感的重要工具。本节将详细介绍如何使用渐变和阴影来增强界面的视觉效果。
一、渐变基础
1.1 什么是渐变
渐变是指在两个或多个颜色之间创建平滑过渡的效果。RmlUi 支持线性渐变和径向渐变。
1.2 渐变类型
- 线性渐变(Linear Gradient)
- 径向渐变(Radial Gradient)
- 锥形渐变(Conic Gradient,部分支持)
二、线性渐变
2.1 linear-gradient 基本语法
css
/* 基本语法 */
linear-gradient(direction, color-stop1, color-stop2, ...);
/* 简单示例 */
background: linear-gradient(to right, red, blue);2.2 方向设置
css
/* 使用关键字 */
background: linear-gradient(to right, red, blue);
background: linear-gradient(to left, red, blue);
background: linear-gradient(to bottom, red, blue);
background: linear-gradient(to top, red, blue);
/* 对角线 */
background: linear-gradient(to bottom right, red, blue);
background: linear-gradient(to top left, red, blue);
/* 使用角度 */
background: linear-gradient(90deg, red, blue); /* 从左到右 */
background: linear-gradient(180deg, red, blue); /* 从上到下 */
background: linear-gradient(45deg, red, blue); /* 对角线 */
background: linear-gradient(-45deg, red, blue); /* 反向对角线 */2.3 颜色停止点
css
/* 两个颜色 */
background: linear-gradient(to right, red, blue);
/* 多个颜色 */
background: linear-gradient(to right, red, yellow, green, blue);
/* 指定位置 */
background: linear-gradient(to right,
red 0%,
yellow 30%,
green 70%,
blue 100%
);
/* 使用长度单位 */
background: linear-gradient(to right,
red 0px,
yellow 100px,
green 200px,
blue 300px
);
/* 省略位置(自动分配) */
background: linear-gradient(to right, red, yellow, green, blue);2.4 透明度渐变
css
/* 使用 rgba */
background: linear-gradient(to right,
rgba(255, 0, 0, 1),
rgba(255, 0, 0, 0)
);
/* 使用 hex 透明度 */
background: linear-gradient(to right,
#ff0000ff,
#ff000000
);2.5 重复线性渐变
css
/* 重复渐变 */
background: repeating-linear-gradient(
45deg,
red,
red 10px,
blue 10px,
blue 20px
);三、径向渐变
3.1 radial-gradient 基本语法
css
/* 基本语法 */
radial-gradient(shape size at position, color-stop1, color-stop2, ...);
/* 简单示例 */
background: radial-gradient(circle, red, blue);3.2 形状设置
css
/* 圆形 */
background: radial-gradient(circle, red, blue);
/* 椭圆(默认) */
background: radial-gradient(ellipse, red, blue);3.3 大小设置
css
/* 关键字 */
background: radial-gradient(circle closest-side, red, blue);
background: radial-gradient(circle closest-corner, red, blue);
background: radial-gradient(circle farthest-side, red, blue);
background: radial-gradient(circle farthest-corner, red, blue);
/* 长度单位 */
background: radial-gradient(circle 100px, red, blue);
background: radial-gradient(ellipse 200px 100px, red, blue);3.4 位置设置
css
/* 中心(默认) */
background: radial-gradient(circle at center, red, blue);
/* 使用关键字 */
background: radial-gradient(circle at top, red, blue);
background: radial-gradient(circle at bottom, red, blue);
background: radial-gradient(circle at left, red, blue);
background: radial-gradient(circle at right, red, blue);
/* 使用位置 */
background: radial-gradient(circle at 50% 50%, red, blue);
background: radial-gradient(circle at 20% 30%, red, blue);3.5 颜色停止点
css
/* 多个颜色 */
background: radial-gradient(circle,
red,
yellow,
green,
blue
);
/* 指定位置 */
background: radial-gradient(circle,
red 0%,
yellow 30%,
green 60%,
blue 100%
);3.6 重复径向渐变
css
/* 重复渐变 */
background: repeating-radial-gradient(
circle,
red,
red 10px,
blue 10px,
blue 20px
);四、使用装饰器应用渐变
在 RmlUi 中,渐变通常通过装饰器(decorator)应用。
4.1 linear-gradient 装饰器
css
.element {
decorator: linear-gradient(to right, red, blue);
}
/* 使用百分比 */
.element {
decorator: linear-gradient(90deg, #fff3, #fff 10%, #c33 250dp, #3c3, #33c, #000 90%, #0003);
}
/* 对角线 */
.element {
decorator: linear-gradient(to bottom right, #ff0000, #0000ff);
}4.2 radial-gradient 装饰器
css
.element {
decorator: radial-gradient(circle, red, blue);
}
/* 指定大小和位置 */
.element {
decorator: radial-gradient(circle 200px at center, red, blue);
}4.3 horizontal-gradient 装饰器
css
.element {
decorator: horizontal-gradient(#f00, #ff0);
}
/* 多个颜色 */
.element {
decorator: horizontal-gradient(#f00, #ff0, #0f0, #00f);
}4.4 vertical-gradient 装饰器
css
.element {
decorator: vertical-gradient(#f00, #00f);
}五、阴影
5.1 box-shadow - 盒阴影
为元素的盒模型添加阴影。
css
/* 基本语法 */
box-shadow: offset-x offset-y blur-radius spread-radius color inset;
/* 简单阴影 */
.element {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3);
}
/* 示例说明 */
.element {
/* offset-x: 5px 水平偏移 */
/* offset-y: 5px 垂直偏移 */
/* blur-radius: 10px 模糊半径 */
/* spread-radius: 0 扩散半径 */
/* color: rgba(0, 0, 0, 0.3) 颜色 */
}5.2 box-shadow 参数详解
css
/* 只设置偏移 */
.element {
box-shadow: 10px 10px #000;
}
/* 设置模糊 */
.element {
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3);
}
/* 设置扩散 */
.element {
box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.3);
}
/* 内部阴影 */
.element {
box-shadow: inset 5px 5px 10px rgba(0, 0, 0, 0.3);
}
/* 无阴影 */
.element {
box-shadow: none;
}5.3 多重阴影
css
/* 多个阴影 */
.element {
box-shadow:
5px 5px 10px rgba(0, 0, 0, 0.3),
-5px -5px 10px rgba(255, 255, 255, 0.3);
}
/* 三层阴影 */
.element {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24),
0 0 10px rgba(0, 0, 0, 0.1);
}5.4 常见阴影效果
css
/* 柔和阴影 */
.soft-shadow {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 深度阴影 */
.deep-shadow {
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
/* 发光效果 */
.glow {
box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
}
/* 浮起效果 */
.float {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* 按下效果 */
.pressed {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}
/* 边框效果 */
.border-effect {
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.1),
0 2px 4px rgba(0, 0, 0, 0.1);
}六、实际应用示例
6.1 按钮渐变效果
css
.button {
padding: 10px 20px;
border: none;
border-radius: 4px;
color: white;
cursor: pointer;
decorator: linear-gradient(to bottom, #3498db, #2980b9);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
transition: box-shadow 0.2s ease-out;
}
.button:hover {
decorator: linear-gradient(to bottom, #48a9e8, #3498db);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
.button:active {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}6.2 卡片阴影效果
css
.card {
width: 300px;
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease-out;
}
.card:hover {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}6.3 渐变背景
css
/* 线性渐变背景 */
.background {
decorator: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
/* 径向渐变背景 */
.background {
decorator: radial-gradient(circle at center, #667eea, #764ba2);
}
/* 多色渐变 */
.background {
decorator: linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff);
}6.4 进度条渐变
css
.progress-bar {
width: 200px;
height: 20px;
background: #e0e0e0;
border-radius: 3px;
overflow: hidden;
}
.progress-fill {
height: 100%;
width: 75%;
decorator: linear-gradient(to right, #3498db, #2ecc71);
border-radius: 3px;
transition: width 0.5s ease-out;
}6.5 文本阴影效果
css
/* 注意:RmlUi 使用 font-effect 而不是 text-shadow */
.text-glow {
font-effect: glow(2dp #354c2e);
}
/* 或者使用 drop-shadow 滤镜 */
.text-shadow {
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.5));
}6.6 3D 卡片效果
css
.card {
width: 300px;
height: 400px;
background: white;
border-radius: 12px;
box-shadow:
0 4px 6px rgba(0, 0, 0, 0.1),
0 1px 3px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease-out, box-shadow 0.3s ease-out;
}
.card:hover {
transform: translateY(-5px);
box-shadow:
0 10px 20px rgba(0, 0, 0, 0.15),
0 3px 6px rgba(0, 0, 0, 0.1);
}6.7 渐变边框
css
.border-gradient {
padding: 20px;
background: white;
border-radius: 8px;
position: relative;
}
.border-gradient::before {
content: "";
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(to right, red, blue);
border-radius: 8px;
z-index: -1;
}七、高级技巧
7.1 渐变动画
css
.element {
decorator: linear-gradient(to right, #ff0000, #0000ff);
transition: filter 0.3s ease-out;
}
.element:hover {
filter: hue-rotate(90deg);
}7.2 阴影动画
css
.element {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease-out;
}
.element:hover {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}7.3 动态阴影
cpp
// C++ 代码:动态更新阴影
void updateShadow(int intensity) {
auto element = document->GetElementById("card");
float opacity = intensity / 100.0f;
String shadow = String(8, "0 %dpx %dpx rgba(0, 0, 0, %.2f)",
intensity, intensity * 2, opacity);
element->SetProperty("box-shadow", shadow);
}7.4 复杂渐变组合
css
/* 多重渐变 */
.element {
decorator:
linear-gradient(to right, rgba(255, 0, 0, 0.5), rgba(0, 0, 255, 0.5)),
linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.3));
}八、性能优化
8.1 渐变性能
css
/* 好的做法:简单渐变 */
.good {
decorator: linear-gradient(to right, red, blue);
}
/* 避免:复杂渐变 */
.bad {
decorator: linear-gradient(45deg,
rgba(255, 0, 0, 1) 0%,
rgba(255, 255, 0, 1) 10%,
rgba(0, 255, 0, 1) 20%,
rgba(0, 255, 255, 1) 30%,
rgba(0, 0, 255, 1) 40%,
rgba(255, 0, 255, 1) 50%,
rgba(255, 0, 0, 1) 100%
);
}8.2 阴影性能
css
/* 好的做法:简单阴影 */
.good {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 避免:过多阴影 */
.bad {
box-shadow:
0 1px 3px rgba(0, 0, 0, 0.12),
0 1px 2px rgba(0, 0, 0, 0.24),
0 3px 6px rgba(0, 0, 0, 0.1),
0 10px 20px rgba(0, 0, 0, 0.15);
}8.3 使用 will-change
css
/* 提示浏览器优化 */
.animated-element {
will-change: box-shadow;
transition: box-shadow 0.3s ease-out;
}九、常见问题
9.1 渐变不显示
问题:设置了渐变但不显示。
原因:
- 元素没有尺寸
- 渐变颜色相同
- 渐变语法错误
解决方案:
css
/* 确保元素有尺寸 */
.element {
width: 100px;
height: 100px;
decorator: linear-gradient(to right, red, blue);
}
/* 确保颜色不同 */
.element {
decorator: linear-gradient(to right, red, red); /* 无效果 */
decorator: linear-gradient(to right, red, blue); /* 有效 */
}9.2 阴影不显示
问题:设置了阴影但不显示。
原因:
- 元素没有背景
- 阴影颜色透明
- 阴影值太小
解决方案:
css
/* 确保元素有背景 */
.element {
background: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
/* 确保阴影可见 */
.element {
box-shadow: 0 0 0 rgba(0, 0, 0, 0); /* 不可见 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); /* 可见 */
}9.3 渐变与边框冲突
问题:渐变与边框同时显示时出现冲突。
解决方案:
css
/* 使用背景裁剪 */
.element {
border: 2px solid #333;
decorator: linear-gradient(to right, red, blue);
box-sizing: border-box;
}
/* 或者使用伪元素 */
.element {
position: relative;
border: 2px solid #333;
}
.element::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
decorator: linear-gradient(to right, red, blue);
z-index: -1;
}十、实战练习
练习 1:创建渐变按钮
创建一个带有渐变效果的按钮:
- 悬停时有颜色变化
- 点击时有阴影变化
- 禁用状态有特殊效果
练习 2:设计卡片系统
创建一个卡片系统:
- 卡片有柔和的阴影
- 悬停时有浮起效果
- 支持不同深度的阴影
练习 3:实现进度条
创建一个带有渐变的进度条:
- 进度条有渐变填充
- 支持动画过渡
- 有阴影效果
练习 4:制作背景效果
创建一个带有渐变的背景:
- 使用多种渐变组合
- 支持动态变化
- 有层次感
十一、下一步
继续学习 粒子特效 来了解如何创建粒子系统。