Communitygithub.com

floorvanriet/wireframe

根据文字描述创建中等保真度线框图,生成自包含的 HTML/CSS 文件。适用于“制作一个……的线框图”、“画出……的结构”、“让我看看 X 会是什么样子”、“为……做线框图”等请求。

wireframe 是什么?

该技能(skill)旨在通过 AI 代理(如 Claude、Cursor、Codex 等)将用户的文字描述转化为可直接预览的中等保真度(mid-fi)线框图,输出为一个独立的 HTML/CSS 文件。其核心价值在于:使用真实的文案(而非‘Lorem ipsum’)和灰度色彩搭配一种强调色(accent),使界面结构清晰可辨;通过两侧并排放置多个屏幕来直观展示流程;利用 Lucide 图标和悬停状态提升交互真实感。技能强调服务于创意过程:要求 AI 在制作前与用户‘切磋’(spar),提出 2-3 个关键设计选择,而不是直接闷头构建;对于探索性需求则先讨论再决定是否制作。最终产出物可直接用于向利益相关者展示或作为迭代讨论的基础。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/floorvanriet/wireframe-skill/tree/HEAD/wireframe

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

线框图

创建中等保真度线框图,作为单个自包含 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 个以上屏幕或一个流程),问一个聚焦的问题:“你想改进什么:概览、速度、信任,还是其他?”

对于单个屏幕或意图已经清晰的情况,不要提问。


针对每种输入类型的方法

用文字描述的屏幕或流程

  1. 确定描述中的屏幕(每个屏幕 = 一个框架)
  2. 确定设备类型(未说明时,移动端应用使用 mobile,网页使用 desktop)
  3. 将所有框架放在一个文件中,并排显示
  4. 使用适合上下文的真实文案,使用最终用户的语言(见核心原则)

框架数量

  • 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。非交互式元素(文本、标签、占位符、不可点击的卡片)则不需要。

相关技能