HarmonyOS6 界面视觉设计细节:阴影、圆角与图文混排的层次感

一个界面"好不好看",往往不是靠复杂的动效或华丽的插图,而是靠无数个视觉细节的叠加。阴影、圆角、颜色层次、文字排版——这些东西每一个单独拿出来都不起眼,组合在一起却能让界面看起来"精致"。
HarmonyOS6 ArkUI 在视觉样式方面提供了相当完整的支持,从 shadow 投影到 borderRadius 圆角,从 TextDecorationType 删除线到 Blank() 弹性间距,几乎所有常见的视觉需求都有对应 API。

在 HarmonyOS PC 端开发中,视觉细节的重要性被进一步放大。PC 端屏幕更大、可视内容更多,用户离屏幕的距离更近,细微的视觉瑕疵都会被放大。一个在手机上看起来还不错的界面,放到 PC 端可能就显得粗糙了。
本文以商品卡片为具体案例,把这些视觉细节逐一拆解,聊聊背后的设计思路。
卡片阴影:给界面加一点"深度"
.shadow({ radius: 8, color: '#1A000000', offsetX: 0, offsetY: 2 })

shadow 接收四个参数:
radius:模糊半径,值越大阴影越扩散、越柔和color:阴影颜色,支持带透明度的 ARGB 格式offsetX/offsetY:阴影偏移量,offsetY: 2表示阴影略微往下偏移
颜色 #1A000000 的含义是:#1A = 十进制 26,对应透明度约 10% 的纯黑。这种极淡的阴影,肉眼感受不到明显的"黑色",只能感受到卡片跟背景之间有一道微弱的分隔——这正是"Material Design"式卡片效果的精髓,若有若无,恰到好处。
阴影参数的设计原则:
| 场景 | radius | 透明度 | offsetY | 适用场景 |
|---|---|---|---|---|
| 轻微层次 | 4-8 | 10-15% | 1-2 | 卡片、按钮 |
| 中等层次 | 8-16 | 15-25% | 2-4 | 弹窗、浮层 |
| 强烈层次 | 16-32 | 25-40% | 4-8 | 对话框、菜单 |
在 HarmonyOS PC 端,阴影的使用更加讲究——PC 端屏幕更大,用户离屏幕更近,过重的阴影会显得廉价。通常建议使用 10%-15% 透明度的阴影,radius 控制在 8-12 之间。
如果把 color 改成 #66000000(透明度约 40%),阴影就会变得非常重,看起来像是卡片浮得很高,反而不够自然。移动端界面通常选 10%-20% 透明度的阴影,既有层次感,又不会干扰主要内容的阅读。
圆角:让界面"柔和"起来
.borderRadius(14) // 卡片整体
.borderRadius(10) // 左侧图片区
.borderRadius(18) // 右侧按钮
.borderRadius(4) // 标签
同一个界面里,不同层级、不同功能的元素用了不同大小的圆角:
- 卡片整体 14vp,大圆角传递"友好、现代"的视觉感受
- 图片区 10vp,稍小一点,与卡片形成视觉层次
- 按钮 18vp(宽高都是 36vp,所以实际上是完整的圆形),圆形按钮在小尺寸下看起来更精致
- 标签 4vp,小圆角表示这是一个"徽章"而非卡片
圆角的设计原则:
| 元素类型 | 推荐圆角 | 视觉感受 |
|---|---|---|
| 大卡片/面板 | 12-16vp | 友好、现代 |
| 小卡片/条目 | 8-12vp | 精致、清晰 |
| 按钮 | 4-8vp(矩形)/ 50%(圆形) | 可点击、亲和 |
| 标签/徽章 | 2-6vp | 紧凑、紧凑 |
| 图片 | 4-10vp | 柔和、不刺眼 |
同一个界面里,圆角大小应该有呼应,不要出现"有些地方是直角、有些地方是大圆角"的割裂感。
在 HarmonyOS PC 端,圆角的设计需要更加谨慎——PC 端界面元素更多、更大,圆角的不一致会更加明显。建议在设计初期就确定一套圆角规范,并在整个应用中统一使用。
颜色语义:颜色不只是装饰
// 现价:红色,紧迫感、促销感
Text(item.price)
.fontColor('#FF4D4D')
// 原价:灰色删除线,"这是打折前的价格"
Text(item.originalPrice)
.fontColor('#BBBBBB')
.decoration({ type: TextDecorationType.LineThrough })
// 标签背景:与标签颜色对应的浅色,视觉上柔和
Text(item.tag)
.fontColor(item.tagColor)
.backgroundColor(item.bgColor)
红色的价格是电商界面的行业惯例,传递出"优惠、促销、紧迫"的心理暗示。灰色配删除线的原价,告诉用户"这是划掉的旧价格",字面和视觉双重确认。
标签的配色方案也很讲究:tagColor 是主色(如绿色 #07C160),bgColor 是对应的极浅底色(如 #F0FFF4)。这种"深色文字 + 浅色背景"的标签设计,颜色醒目但不刺眼,常见于各类 App 的状态标签、分类标签。
颜色语义的设计原则:
| 颜色 | 语义 | 适用场景 |
|---|---|---|
| 红色 (#FF4D4D) | 危险、促销、重要 | 价格、错误提示、删除按钮 |
| 橙色 (#FF8C00) | 警告、推荐 | 限时优惠、热门推荐 |
| 绿色 (#07C160) | 成功、安全、新增 | 成功提示、新增标签、通过状态 |
| 蓝色 (#007DFF) | 信息、链接、选中 | 链接、选中态、主按钮 |
| 灰色 (#999999) | 次要、禁用、辅助 | 辅助文字、禁用状态、占位符 |
在 HarmonyOS PC 端,颜色的使用还需要考虑无障碍设计——确保颜色对比度符合 WCAG 2.1 AA 标准(至少 4.5:1),让色弱用户也能正常阅读内容。
Blank():最简单的弹性间距
Row() {
Text('商品列表')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
Blank()
Text('查看全部 >')
.fontSize(14)
.fontColor('#007DFF')
}
.width('100%')
.padding({ left: 16, right: 16, top: 20, bottom: 12 })
Blank() 在 ArkUI 里是一个特殊的弹性组件,它会自动占满容器内的剩余空间。在这里,"商品列表"靠左,"查看全部 >"靠右,中间的间距由 Blank() 自动撑开。屏幕宽度变了,间距跟着变,永远保持两端对齐。
这比手动设置 margin 或者 padding 要灵活得多——你不需要知道屏幕宽度是多少,只要告诉系统"中间这块儿是弹性空间"就行了。
在 HarmonyOS PC 端,Blank() 的作用更加突出——PC 端窗口可以自由调整大小,用户可能把窗口拉得很宽,也可能缩得很窄。用 Blank() 实现的弹性间距,能确保界面在任何窗口大小下都保持正确的布局。
文字层次:字号与字重的搭配
// 商品名:16号,中等字重
Text(item.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#1A1A1A')
// 标签:11号,正常字重
Text(item.tag)
.fontSize(11)
// 现价:18号,粗体
Text(item.price)
.fontSize(18)
.fontWeight(FontWeight.Bold)
// 原价:13号,正常字重,灰色
Text(item.originalPrice)
.fontSize(13)
.fontColor('#BBBBBB')
整张卡片里,价格数字字号最大(18vp)、最粗(Bold),是视觉焦点。商品名次之(16vp,Medium),是主要信息。标签和原价字号最小,是辅助信息。
文字层次的设计原则:
| 信息级别 | 字号 | 字重 | 颜色 | 适用场景 |
|---|---|---|---|---|
| 一级(焦点) | 18-24vp | Bold | 主色/深色 | 价格、标题 |
| 二级(主要) | 14-18vp | Medium | 深灰 | 商品名、正文 |
| 三级(辅助) | 11-14vp | Regular | 中灰 | 标签、描述 |
| 四级(次要) | 10-12vp | Regular | 浅灰 | 时间、版权信息 |
这种"字号越大越重要,字色越深越重要"的排版原则,叫做视觉层次。用户扫一眼卡片,视线会自然地按"价格 → 商品名 → 标签 → 原价"的顺序流动,符合电商场景"先看价格"的浏览习惯。
在 HarmonyOS PC 端,文字层次的设计同样适用,但需要注意:PC 端屏幕更大,用户可以看得更远,所以字号可以适当放大 10%-20%。建议一级信息用 20-26vp,二级信息用 16-20vp。
间距系统:让界面"透气"
// 卡片内部间距
.padding(14)
// 卡片之间的间距
Column({ space: 12 })
// 卡片阴影内容的左边距
.margin({ left: 14 })
// 标签内边距
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
注意一个规律:主要间距用 12 或 14,细节间距用 6,标签内边距上下 2 左右 6。这并不是随意取的数字,而是基于 4的倍数 规则(4、8、12、16、20…)的间距体系——绝大多数设计系统都采用这套规则,它能让界面的各处留白看起来整齐、和谐。
间距系统的设计原则:
| 间距类型 | 推荐值 | 适用场景 |
|---|---|---|
| 大间距 | 20-24vp | 模块之间、页面边距 |
| 中间距 | 12-16vp | 卡片之间、组之间 |
| 小间距 | 6-8vp | 元素之间、行间距 |
| 极小间距 | 2-4vp | 图标与文字、标签内边距 |
在 HarmonyOS PC 端,间距可以适当放大——PC 端屏幕更大,用户离屏幕更远,较大的间距能让界面看起来更舒展、更透气。建议中间距用 16-20vp,大间距用 24-32vp。
完整案例
下面是完整的视觉设计示例代码,可以直接复制到 DevEco Studio 中运行:
/**
* 视觉设计细节完整示例
* 演示阴影、圆角、颜色层次在 HarmonyOS PC 端的应用
*
* 文件路径:entry/src/main/ets/components/VisualDesignDemo.ets
* 运行环境:DevEco Studio 5.0 + HarmonyOS6 SDK
*/
interface GoodsInfo {
id: number
name: string
price: string
originalPrice: string
tag: string
tagColor: string
bgColor: string
}
@Entry
@Component
struct VisualDesignDemo {
@State selectedId: number = -1
private goodsList: GoodsInfo[] = [
{
id: 1,
name: '无线蓝牙耳机',
price: '¥299',
originalPrice: '¥599',
tag: '限时折扣',
tagColor: '#FF4D4D',
bgColor: '#FFF5F5'
},
{
id: 2,
name: '智能运动手表',
price: '¥899',
originalPrice: '¥1299',
tag: '爆款推荐',
tagColor: '#FF8C00',
bgColor: '#FFF8F0'
},
{
id: 3,
name: '便携充电宝',
price: '¥129',
originalPrice: '¥199',
tag: '新品上架',
tagColor: '#07C160',
bgColor: '#F0FFF4'
},
{
id: 4,
name: '机械键盘',
price: '¥459',
originalPrice: '¥699',
tag: '热销榜一',
tagColor: '#007DFF',
bgColor: '#F0F7FF'
}
]
build() {
Column({ space: 16 }) {
// 顶部标题栏
this.HeaderBar()
// 商品卡片列表
Column({ space: 12 }) {
ForEach(this.goodsList, (item: GoodsInfo) => {
this.GoodsCard(item)
})
}
.padding(16)
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F6FA')
}
@Builder
HeaderBar() {
Row() {
Text('商品列表')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
Blank()
Text('查看全部 >')
.fontSize(14)
.fontColor('#007DFF')
}
.width('100%')
.padding({ left: 16, right: 16, top: 20, bottom: 12 })
}
@Builder
GoodsCard(item: GoodsInfo) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
// 商品图片
Column() {
Text(item.name.substring(0, 1))
.fontSize(28)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Bold)
}
.width(80)
.height(80)
.backgroundColor(item.tagColor)
.borderRadius(10)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
// 商品信息
Column({ space: 6 }) {
Text(item.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#1A1A1A')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(item.tag)
.fontSize(11)
.fontColor(item.tagColor)
.backgroundColor(item.bgColor)
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
.borderRadius(4)
Row({ space: 8 }) {
Text(item.price)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#FF4D4D')
Text(item.originalPrice)
.fontSize(13)
.fontColor('#BBBBBB')
.decoration({ type: TextDecorationType.LineThrough })
}
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 14 })
// 加购按钮
Button('+')
.width(36)
.height(36)
.fontSize(22)
.fontColor('#FFFFFF')
.backgroundColor(this.selectedId === item.id ? '#FF4D4D' : '#007DFF')
.borderRadius(18)
.margin({ left: 14 })
.onClick(() => {
this.selectedId = item.id
})
}
.width('100%')
.padding(14)
.backgroundColor('#FFFFFF')
.borderRadius(14)
.shadow({ radius: 8, color: '#1A000000', offsetX: 0, offsetY: 2 })
.border({
width: this.selectedId === item.id ? 2 : 0,
color: '#007DFF'
})
.onClick(() => {
this.selectedId = item.id
})
}
}

常见问题与解决方案
1. 阴影在低性能设备上卡顿
问题:大量卡片同时显示阴影,导致滚动卡顿。
解决方案:
- 使用
cache(false)禁用缓存,让框架动态计算阴影 - 或者使用
border模拟阴影,降低渲染开销 - 考虑使用
LazyForEach实现虚拟列表,只渲染可见区域
2. 圆角导致内容溢出
问题:设置了 borderRadius,但子元素超出了圆角边界。
解决方案:
.borderRadius(14)
.clip(true) // 裁剪超出圆角边界的子内容
3. 颜色对比度不足
问题:文字颜色与背景色对比度太低,影响阅读。
解决方案:使用 WCAG 颜色对比度检测工具,确保对比度至少达到 4.5:1(AA 标准)或 7:1(AAA 标准)。
写在最后
视觉细节是界面品质的分水岭,而 HarmonyOS6 ArkUI 已经把大量细节控制能力暴露出来了,阴影透明度、圆角大小、字号层级、弹性间距……每个属性都能精确控制。
真正的设计功夫不在于"用了多少 API",而在于对每个参数的取值有清晰的意图:这个阴影为什么是 10% 透明度而不是 30%?这个圆角为什么是 14 而不是 8?这个字号为什么是 16 而不是 18?当你能回答这些问题,界面自然就做得好看了。
在 HarmonyOS PC 端开发中,视觉细节的重要性被进一步放大。PC 端屏幕更大、用户离屏幕更近,细微的视觉瑕疵都会被放大。建议在开发初期就建立一套完整的设计规范,包括颜色体系、圆角体系、字号体系、间距体系,并在整个应用中统一使用。
最后一点,颜色要有系统性——主色、辅助色、背景色、文字色、危险色,在数据结构层面就确定好,通过数据驱动样式,而不是在每个组件里各自硬编码一套颜色。这样日后修改主题、调整配色,改一个地方就够了。
更多推荐


所有评论(0)