UI设计基础与设计系统:从原子到座舱

UI设计,说白了就是让用户看得懂、用得顺。但在座舱HMI里,光好看没用。你得考虑多屏联动、驾驶安全、硬件性能。我做了这么多年,最大的体会是——没有设计系统,多屏互动就是一场灾难。

今天咱们聊聊设计规范、原子设计理论,还有色彩和字体怎么选。最后我会分享一套实战级的设计系统搭建方法。

为什么座舱HMI需要设计系统?

你想想看,一个座舱里可能有仪表屏、中控屏、副驾屏、HUD。如果每块屏的按钮风格不一样,字体大小不统一,用户会疯的。更别提还要做多屏流转——导航从中控飞到仪表,音乐从仪表飞到副驾。

设计系统就是解决这个问题的。它是一套可复用的组件库和规则集。保证所有屏幕看起来像同一辆车,而不是拼凑出来的。

核心观点:设计系统不是设计文档,是可执行的代码级规范。它决定了你的HMI能否高效迭代。

原子设计理论:从原子到页面

Brad Frost提出的原子设计理论,我特别喜欢。它把UI拆成五个层级:

层级 定义 座舱HMI举例
原子 最小的UI元素 图标、颜色、字体、间距
分子 原子组合成功能单元 按钮、输入框、滑块
组织 分子组合成模块 导航栏、卡片列表、媒体控制区
模板 组织组合成页面布局 仪表盘布局、中控主页布局
页面 模板填充真实内容 具体车型的仪表盘、中控界面

我在项目中遇到过一个问题:设计师直接画页面,结果每个页面风格都不一样。后来我们改用原子设计,先定义好所有原子(颜色、字体、间距),再组合成分子(按钮、卡片),最后拼页面。效率提升了一倍。

色彩系统:别让颜色毁了驾驶

座舱HMI的色彩设计,跟手机APP完全不同。驾驶场景下,颜色不能刺眼,不能分散注意力。

我个人习惯用「70-25-5」法则:

  • 70% 主色:深色背景(#1a1a2e 或 #0f0f1a),减少反光
  • 25% 辅助色:中性灰(#3a3a4a 到 #6a6a7a),用于卡片、分割线
  • 5% 强调色:品牌色或功能色,用于关键信息

避坑指南:我曾经在项目里用了亮蓝色作为强调色,结果夜间模式下刺眼到不行。后来改成低饱和度的青色(#4fc3f7),白天看得清,晚上不晃眼。

色彩还要考虑色盲用户。红绿色盲在男性中占8%。所以重要信息(如警告、故障)不能只靠颜色区分,必须配合图标或文字。

字体系统:可读性第一

座舱里字体选择,我只看三点:

  1. 无衬线字体:比如Noto Sans、Roboto、思源黑体。衬线字体在屏幕上容易糊。
  2. 字重适中:Regular(400)用于正文,Medium(500)用于标题,Bold(700)用于警告。
  3. 字号阶梯:从12px到48px,每级差2px或4px。

我建议的字号系统:

用途 字号 字重 行高
仪表盘主数字 48px Bold 1.0
页面标题 28px Medium 1.2
列表项标题 20px Medium 1.4
正文 16px Regular 1.5
辅助文字 14px Regular 1.4
标签/角标 12px Regular 1.2

注意:座舱里字体最小不要低于12px。我见过有项目用10px的标签,驾驶员根本看不清,差点出事。

设计系统搭建实战

好,理论说完了。咱们直接上手搭建一个座舱HMI设计系统。我会用CSS变量来演示,因为这是最直观的方式。

第一步:定义设计Token

/* 颜色Token */
:root {
  --color-bg-primary: #0f0f1a;
  --color-bg-secondary: #1a1a2e;
  --color-bg-card: #2a2a3e;
  --color-text-primary: #ffffff;
  --color-text-secondary: #a0a0b0;
  --color-accent: #4fc3f7;
  --color-warning: #ff7043;
  --color-danger: #ef5350;
  --color-success: #66bb6a;
}

/* 字体Token */
:root {
  --font-family: 'Noto Sans SC', sans-serif;
  --font-size-display: 48px;
  --font-size-title: 28px;
  --font-size-body: 16px;
  --font-size-caption: 14px;
  --font-size-label: 12px;
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-bold: 700;
  --line-height-tight: 1.0;
  --line-height-normal: 1.4;
  --line-height-loose: 1.6;
}

/* 间距Token */
:root {
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;
  --spacing-2xl: 48px;
}

第二步:构建原子组件

/* 按钮原子 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: 8px;
  font-family: var(--font-family);
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-medium);
  border: none;
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-primary {
  background: var(--color-accent);
  color: var(--color-bg-primary);
}

.btn-primary:hover {
  opacity: 0.9;
}

.btn-danger {
  background: var(--color-danger);
  color: var(--color-text-primary);
}

/* 卡片分子 */
.card {
  background: var(--color-bg-card);
  border-radius: 12px;
  padding: var(--spacing-md);
  margin-bottom: var(--spacing-md);
}

.card-title {
  font-size: var(--font-size-title);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-primary);
  margin-bottom: var(--spacing-sm);
}

.card-body {
  font-size: var(--font-size-body);
  color: var(--color-text-secondary);
  line-height: var(--line-height-normal);
}

第三步:组合成组织模块

/* 导航栏组织 */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-sm) var(--spacing-md);
  background: var(--color-bg-secondary);
  border-bottom: 1px solid var(--color-bg-card);
}

.navbar-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  color: var(--color-text-secondary);
  font-size: var(--font-size-caption);
}

.navbar-item.active {
  color: var(--color-accent);
}

/* 媒体控制区组织 */
.media-controls {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  padding: var(--spacing-md);
  background: var(--color-bg-card);
  border-radius: 12px;
}

.media-controls .btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
}

第四步:组装模板和页面

这部分就是具体布局了。比如仪表盘模板,左边放车速,右边放转速,中间放辅助信息。中控模板,顶部导航,中间内容区,底部dock栏。

嗯,这里要注意:模板层不要写死内容。模板只定义位置和间距,内容由页面层填充。这样同一个模板可以适配不同车型。

设计系统的多屏适配

座舱里屏幕尺寸差异很大。仪表盘通常是1920x720,中控是1920x1080,副驾可能是1280x720。设计系统必须支持响应式。

我建议用「断点+栅格」方案:

  • 小屏(HUD、副驾):4列栅格,间距12px
  • 中屏(仪表盘):6列栅格,间距16px
  • 大屏(中控、副驾大屏):12列栅格,间距16px

每个组件都要定义在小屏、中屏、大屏下的表现。比如按钮,小屏下只显示图标,中屏下图标+文字,大屏下图标+文字+副标题。

实战经验:我做过一个项目,中控屏和副驾屏共享同一个组件库。但副驾屏分辨率低,按钮间距不够。后来我们在组件里加了 --screen-density 变量,根据屏幕密度自动调整间距和字号。

设计系统的版本管理

设计系统不是一次建完就完事了。车型迭代、功能更新,设计系统也要跟着升级。

我推荐用语义化版本号:

  • 主版本号:不兼容的API修改(比如颜色体系全换)
  • 次版本号:向下兼容的功能新增(比如新增一个组件)
  • 修订号:向下兼容的问题修正(比如修复某个组件的间距)

每次更新都要写变更日志。我在团队里强制要求:不改日志,不准合并代码。

SVG:设计系统知识结构图

下面这张图,把设计系统的核心脉络画清楚了。从设计Token到底层组件,再到业务模块,最后到多屏适配。你一看就明白。

座舱HMI设计系统知识结构 座舱HMI设计系统知识结构 设计Token(原子) 颜色 | 字体 | 间距 | 圆角 | 阴影 | 动画 原子组件(分子) 按钮 | 输入框 | 滑块 | 开关 | 图标 | 标签 业务模块(组织) 导航栏 | 媒体控制 | 空调面板 | 仪表盘 | 通知中心 多屏适配(模板+页面) 仪表盘 | 中控屏 | 副驾屏 | HUD | 后排屏 💡 每一层都向下依赖,向上提供接口。修改Token会影响所有组件。 版本管理:主版本号(不兼容)→ 次版本号(新增)→ 修订号(修复)

总结一下

设计系统不是一次性的工作。它需要持续维护、持续迭代。但一旦建好了,你会发现多屏互动变得特别顺畅。所有屏幕共用一套组件,数据流转、状态同步都变得可控。

我建议你从今天开始,哪怕只是一个小项目,也试着用原子设计理论去搭建。先定义颜色和字体,再构建按钮和卡片,最后组装页面。你会发现,设计系统带来的效率提升,远超你的预期。