线框图
创建中等保真度线框图,作为单个自包含 HTML 文件输出。多个屏幕并排显示,响应式设计,灰度搭配一种强调色,使用真实文案。
核心原则
中保真度意味着:
- 使用灰度调色板(见下方的设计令牌),外加一种强调色(
--accent)用于主要操作和活跃状态。这样主操作一目了然;不要使用其他颜色。 - 使用真实的标签、标题和标题,不要用“Lorem ipsum”。撰写最终用户会看到的语言文案;如果不明确,则使用请求所用的语言。这样即使对话以另一种语言进行,线框图也可以直接展示给利益相关者。
- 用占位块来表示图片(不使用真实素材)
- 在有意义的图标处使用 Lucide 线条图标(参见图标章节)
- 对所有可点击元素应用悬停状态(参见悬停状态)
- 清晰的字体层级
- 无装饰、无阴影,仅使用细微的边框
绝对不要:
- 使用品牌颜色,或除强调色之外的任何颜色
- 使用真实图片、照片、标志或插图
- 使用表情符号或文本符号作为图标(☰、×、›):请使用 Lucide
- 添加动画(悬停时使用简短的
transition是可以的) - 在线框图内部添加解释(注释应放在线框图外部)
支持创意过程
线框图是一种思考工具:它帮助用户通过大声推理、质疑和迭代来理清“做什么”和“为什么”。你的工作是支持这个过程,而不是接管它。这意味着两方面:既不要不加讨论就直接构建,也不要在画布上出现任何东西之前就用大量讨论淹没用户。屏幕是对话的素材,而不是交付物。
针对不同类型的输入
- 新请求: 开始回复时使用简短切磋块:提出 2-3 个最重要的选择,每个选择附带选项、你的偏好以及理由。包括交互(不仅仅是布局):点击或触摸时会发生什么,反馈出现在哪里,哪些操作可以撤销,是使用模态框还是新页面,是内联操作还是额外步骤。然后按你的偏好选项进行构建,以便有具体的东西可以回应。用几个要点即可,不要写长篇大论。(请求模糊且范围复杂?请先从“优化意图”章节中提出那一个问题。)
- 探索性请求(“我在……之间犹豫不决”、“什么对……有效”、思考中):仅进行切磋。列出选项及其权衡和你的偏好,然后询问是否要构建其中一个,以及构建哪一个。
- 后续输入: 首先对实质内容做出回应:一起思考、补充内容、指出弱点或提出替代方案。只有在对某事做出决定后才修改线框图,而不是每次有想法就修改。不确定是切磋还是决策?简单问一句:“我应该应用这个,还是先思考一下?”
如何切磋
- 大声提出质疑。 如果某个模式在此上下文中可能不起作用(例如,当只有两个项目时使用短列表),请说出来,而不是盲目地构建它。
- 提供方向,而非定案。 当选择真正开放时,在线框图中并排展示方案 A 和 B,而不是仅仅描述它们,并说出你更倾向于哪一个。
- 小步迭代。 预期每个元素都会发生变化。根据用户的选择或指向进行构建。
- 不要强迫做决定。 目标是清晰;选择可以稍后进行。
- 保持简洁。 每个选项一行,总共几个要点,最多一个聚焦的问题。线框图本身会说话,所以不要逐项解释其中的内容;只提及用户看不到的内容,例如某个假设或点击后会发生什么。
UX 原则
- 质疑概念,而不仅仅是布局。 持续检查底层功能是否真的站得住脚,并对此提出挑战,而不仅仅是“它看起来像什么”。
- 不要声称系统无法知道的状态。 基于可用数据构建 UI。如果某些信息无法获知,则显示操作而不是状态,或者让用户自己标记。
- 使内容保真度与屏幕目的相匹配。 如果重点是结构或导航,则使内容低保真(占位线),以便焦点保持在主题上。
- 将关键状态并排进行线框化。 登录/退出、空/满、打开/关闭:这样才能看到真正的决策。
- 有意识地将导航转换为小屏幕。 保留一个持久的锚点,以使过渡不突兀;优先考虑并分组,而不是显示所有内容。一个导航结构,多种外壳,一个来源。
交付
- 将每个线框图保持为单个自包含 HTML 文件。 旁边不要有单独的 JS/CSS 文件:预览通常以独立方式渲染文件,没有兄弟文件。基础模板中的两个 CDN 链接(IBM Plex Sans 通过 Google Fonts,Lucide 通过 jsDelivr)是例外;这些在预览中加载正常。想要复用?内联主模板并同步副本。
- 对于大量屏幕,添加固定的屏幕切换器(例如下拉菜单)以便在屏幕之间跳转。
- 对于跨越多个产品部分的概念,构建一个概念站点(见下文)。
概念站点
当一个概念涵盖产品多个部分(如入门、搜索、账户……)并且用户想要将其作为一个整体展示或审查时,构建一个概念站点:每个部分一个页面,通过相同的菜单栏连接。利益相关者可以在一个地方浏览整个概念,并且你可以迭代一个部分而无需触碰其余部分。
- 菜单栏 位于画布上每个页面的顶部,在框架之上。左侧:概念名称,带有一个
info图标,其工具提示包含版本、日期和一行说明。然后一个分隔符,然后每个部分一个链接。当前页面获取aria-current="page"并样式化为--text-primary/600;其余部分用--text-secondary。当链接放不下时,栏水平滚动而不是换行。对于大型概念(大约 15 个屏幕以上),在栏的右端添加一个“跳转到屏幕”下拉菜单,可以跳转到任何页面上的任何屏幕;对于较小的概念,菜单就足够了。 - 先做信息架构。 第一个链接是一个 IA 页面:产品的结构,包含每个部分的链接。它也是入口页面。
- 每个部分页面 是一个普通的线框图:并排的框架、框架标签、虚线画布。
- 当文件将一起打开时,使用单独的文件。 如果你可以编写一个用户可以在浏览器中打开或托管的文件夹(在本地工作,在仓库中),则为 IA 创建
index.html,并为每个部分创建一个带有简短短链接的文件(onboarding.html),使用相对链接。 - 当文件将被单独预览时,使用单个文件。 单个工件或聊天预览会独立渲染一个文件,因此指向其他文件的链接会断开。将所有部分放在一个文件中作为章节,通过菜单使用
#hash链接(#onboarding)切换。 - 保持菜单在所有地方相同。 从一个主副本内联到每个文件中,这样每个页面仍然可以独立工作。当一个部分被添加、重命名或删除时,同时更新所有文件中的菜单。
设计令牌
:root {
--bg: #F5F5F5; /* 页面背景 */
--surface: #FFFFFF; /* 卡片、面板 */
--border: #D1D1D1; /* 边框 */
--muted: #E8E8E8; /* 占位块 */
--text-primary: #1A1A1A;
--text-secondary: #595959; /* 元数据、占位符、图片块中的标签 */
--text-disabled: #AAAAAA; /* 仅用于禁用控件 */
--accent: #1560D0; /* 唯一的颜色:主要操作、活跃状态 */
--accent-hover: #1250B0;
--hover-bg: #F0F0F0; /* 浅色或透明元素上的悬停 */
--border-hover: #AAAAAA; /* 有边框元素上的悬停 */
--font: 'IBM Plex Sans', system-ui, sans-serif;
}
这些令牌针对 WCAG AA(4.5:1)进行了调整:--text-primary 和 --text-secondary 在此处的所有表面颜色(--surface、--bg、--hover-bg、--muted、--border)上都通过;--accent 作为文本在除 --border 之外的所有颜色上都通过;白色在 --accent 上通过。无障碍从线框图开始,所以请保持这样:不要为文本添加更浅的灰色。唯一的例外是 --text-disabled(2.3:1):仅将其用于禁用控件(WCAG 对此有豁免),切勿用于可读文本(如元数据)。
HTML 结构
基础模板
将 lang 设置为文案的语言。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wireframe: [主语]</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
<style>
/* 令牌 */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; -webkit-font-smoothing: antialiased; }
button, input, select, textarea { font: inherit; } /* 表单控件默认不继承字体 */
/* 布局 + 组件 */
</style>
</head>
<body>
<div class="wireframe-canvas">
<div class="frame-row">
<!-- 框架放在这里 -->
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/lucide@1/dist/umd/lucide.min.js"></script>
<script>lucide.createIcons();</script>
</body>
</html>
多框架布局
这个画布让输出一眼看去就像是线框图,所以请按原样使用。
.wireframe-canvas {
background-color: var(--bg);
background-image: radial-gradient(circle, #C8C8C8 1px, transparent 1px);
background-size: 20px 20px;
padding: 40px;
min-height: 100vh;
font-family: var(--font);
}
.frame-row {
display: flex;
gap: 32px;
align-items: flex-start;
flex-wrap: wrap;
}
.frame {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
flex-shrink: 0;
}
/* 设备宽度 */
.frame.mobile { width: 375px; }
.frame.tablet { width: 768px; }
.frame.desktop { width: 1280px; }
.frame.auto { width: 100%; max-width: 1280px; }
框架标签(每个屏幕上方)
<div class="frame-label">屏幕 1: [名称]</div>
<div class="frame mobile">
<!-- 内容 -->
</div>
.frame-label {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-secondary);
margin-bottom: 8px;
}
组件
自己编写组件的 HTML 和 CSS,但要坚持使用这些值,以便线框图在不同会话间保持一致。为按钮和输入提供 min-height 并使用 inline-flex 居中对齐,而不是依赖内边距:仅靠内边距最终会略低于 40px,而 40px 是最小点击目标。
| 组件 | 规格 |
|---|---|
| 主按钮 | --accent 填充,白色文本,14px/600,min-height: 40px,内边距 0 20px,圆角 6px |
| 次按钮 | 透明,--accent 文本,1.5px --accent 边框,其余同主按钮 |
| 文字按钮 / 内联操作 | “编辑”、“设置状态”、“更改”:--accent 文本,14px/500,无边框。仍需 40px 点击目标:使用 min-height: 40px 配合 inline-flex,或者当它位于文本行内时,使用内边距加上相等的负外边距 |
| 输入框 | 标签在上方(13px/500,--text-primary,间隙 4px)。字段:1px --border,圆角 6px,min-height: 40px,内边距 0 12px,14px,占位符文本使用 --text-secondary |
| 图片占位块 | --muted 色块,带有固定的 aspect-ratio,居中标签使用 --text-secondary 13px,命名内容及比例(“产品照片 16:9”) |
| 卡片 | --surface,1px --border,圆角 8px,overflow: hidden。主体内边距 16px,间距 4px:overline 11px 大写 --text-secondary,标题 15px/600,元数据 12px --text-secondary |
| 标签 | 12px/500,内边距 2px 8px,圆角 4px(比其所在的卡片小),--muted 背景,--text-secondary 文本 |
| 移动端导航栏 | 内边距 12px 16px,底部边框。左侧 Logo 文本 16px/600,右侧 Lucide menu 图标位于 40×40 按钮内,带有 aria-label |
| 桌面端导航栏 | 内边距 16px 32px,底部边框。左侧 Logo,链接(14px,--text-secondary,间距 24px,活跃状态 --text-primary/500),右侧主按钮 |
| 步骤条 | 28px 圆形,13px/600 数字,32px 连接线使用 --border。待办:--muted/--text-secondary。活跃:--accent/白色。已完成:--border/--text-secondary |
需要这里未列出的组件?从这些值(相同的圆角、字号比例和状态)派生,而不是发明新的。
优化意图
如果请求包含方向(“更少的步骤”、“更容易扫描”、“不那么拥挤”、“更容易理解”),将其作为透镜:选择强化该方向的组件、层级和文案结构。
如果请求模糊并且范围复杂(3 个以上屏幕或一个流程),问一个聚焦的问题:“你想改进什么:概览、速度、信任,还是其他?”
对于单个屏幕或意图已经清晰的情况,不要提问。
针对每种输入类型的方法
用文字描述的屏幕或流程
- 确定描述中的屏幕(每个屏幕 = 一个框架)
- 确定设备类型(未说明时,移动端应用使用 mobile,网页使用 desktop)
- 将所有框架放在一个文件中,并排显示
- 使用适合上下文的真实文案,使用最终用户的语言(见核心原则)
框架数量
- 1 个屏幕:按设备宽度显示
- 2-4 个屏幕:在一行中并排显示
- 5 个以上屏幕:两行,或水平滚动
悬停状态
始终添加它们。线框图应该是可点击的,而悬停可以展示哪些内容是交互的。有三种模式。将它们应用于你在这个线框中创建的类,而不是一个固定的列表:
/* 1. 强调色填充:主按钮、活跃 chip 或标签页、浮动操作按钮 */
.btn-primary:hover { background: var(--accent-hover); cursor: pointer; }
/* 2. 浅色或透明:次按钮、图标按钮、列表项 */
.btn-secondary:hover,
.nav-menu:hover { background: var(--hover-bg); cursor: pointer; }
/* 3. 有边框:可点击的卡片、chip、选择选项 */
.card:hover { border-color: var(--border-hover); cursor: pointer; }
每个交互式元素都获得 cursor: pointer。非交互式元素(文本、标签、占位符、不可点击的卡片)则不需要。