做原型这件事,我试过很多路子。早期用画布类工具拖拽矩形,第一版交互确实快,可真到评审阶段就头疼:按钮圆角跟设计规范差了 4 像素,列表间距每页都不一样,产品风格像是后贴上去的贴纸。后来我在一个协同工具项目里引入 Design.md,用 Markdown 写页面结构、组件状态和设计令牌,再渲染成可点击的 HTML 原型,风格终于不用靠手工微调,而是从源头上长出来的。这篇文章既是我自己的完整复盘,也是一套可以直接抄作业的流程。适合产品经理、UX 设计师、前端开发,以及所有被“原型和产品风格两张皮”折磨过的人。
1. 为什么我放弃了纯图形工具,改用 Design.md 搭原型
1.1 图形原型越做越重的真实痛点
画布类工具的优势没人否认:所见即所得、拖拽友好、适合发散创意。但它在推进到“高保真原型”阶段时,问题会集中爆发。最典型的是规范漂移——团队里每个人都在画自己的画板,A 做的按钮主色偏亮,B 做的卡片圆角更大,评审时大家讨论的完全是风格细节,而不是流程和逻辑是否成立。
另一个痛点是版本管理。图形文件虽然也是文件,但 diff 起来极不直观。你很难说清楚“这个版本相比上个版本,到底改了哪些页面的哪些状态”。一旦设计走查要回溯,要么靠人工记忆,要么靠导出的图片一张张对比,效率非常低。我在模拟项目 X 的早期阶段,几乎每次评审会前都要花一两个小时手动核对各个画板是否统一。
第三个痛点是图形工具和设备、平台之间的耦合。换了新电脑、新账号或新协作环境,经常要重新同步字体、插件和组件库。而文本文件天然轻量,Git 能精确记录每一次修改,能分支、能合并、能回溯,这是画布类工具很难做到的。
1.2 Design.md 的核心思路:文本即源头,规范即样式
Design.md 的思路一句话就能说清:用 Markdown 写原型的“内容与结构”,用设计令牌描述“视觉规范”,再用渲染器把这两者合成可浏览的 HTML 原型。Markdown 本身只是承载信息的骨架,真正让页面“符合产品风格”的,是旁边那套设计令牌。
我把这套关系理解成“骨骼与皮肤”。Markdown 段落和标题是骨骼,决定页面有什么;设计令牌是皮肤,决定页面长什么样。两者解耦之后,改风格不需要动页面结构,改结构也不会破坏风格。这在前期探索产品风格时尤其好用:同一套页面文案,换一套令牌就能快速对比深色主题、浅色主题或品牌色方案。
更重要的是,Design.md 的产物是静态 HTML 文件,不需要开图形软件、不需要登录协作账号,任何人都能双击打开或部署到内部服务器。我做演示时会把导出的原型包发给同事,对方不用装任何工具就能点完整个流程。这一点在跨团队评审时极其省心。
1.3 这套方法的定位与边界
先泼一盆冷水:Design.md 不适合做探索期的脑暴工具。发散创意、随手画线框图、快速抛弃方案,这些场景画布类工具依然更快。Design.md 更适合的是“已经确定了产品方向,需要快速产出风格统一、逻辑完整的高保真原型”的阶段。
它也不适合像素级视觉设计。原型的目标是验证信息架构、交互路径和风格方向,不是在原型里雕琢投影和渐变。真到了视觉定稿,还是得交给更专业的视觉稿和设计系统。
明确了定位,你才能判断这套流程适不适合自己。如果你所在的团队已经有成熟的设计系统和组件库,Design.md 还能进一步帮上忙——它可以把设计令牌直接导出成 CSS 变量或设计系统配置,原型和真实代码之间的鸿沟会小很多。
2. 先跑通流程:安装、目录和基础语法
2.1 安装启动:5 分钟跑通本地预览
Design.md 不是单一工具,更像一套约定加一个轻量渲染器。我当前使用的版本基于 Node.js,安装命令很简单,一条全局命令就能完成:
npm install -g design-md装完后,新建一个项目目录并初始化:
mkdir my-proto cd my-proto design-md init初始化命令会生成一套标准目录结构、一个示例页面和一份默认令牌文件。紧接着启动本地预览:
design-md serve浏览器会自动打开一个本地地址,默认端口是 8080。改动任何 Markdown 文件,保存后页面都会即时刷新。这套热更新体验基本等于现代前端工程,但复杂度低得多,没有任何构建配置需要手工维护。
如果你不想全局安装,也可以在当前项目里用npx design-md跑同样的命令。区别其实很小,只是更符合按项目隔离依赖的习惯。我个人建议在长期维护的设计项目里用局部依赖,避免不同项目的 Design.md 版本互相干扰。
2.2 目录结构:页面、组件与令牌分而治之
运行初始化后,目录结构大致如下:
my-proto/ ├── design.md.config.js ├── tokens/ │ └── base.yaml ├── pages/ │ ├── index.md │ ├── login.md │ └── task-detail.md └── components/ ├── button.md ├── task-card.md └── empty-state.mdtokens目录存放设计令牌,pages目录每个文件对应一个原型页面,components目录用于存放可复用的组件片段。分离的核心意义是避免重复劳动:组件定义一次,页面里引用,后续改组件只需改一处。
design.md.config.js是配置文件,我通常只在这里设置站点标题、输出目录和主题名。保持配置尽可能小,项目越容易维护。如果一开始就把复杂的逻辑塞进配置文件,项目很快会变成一团乱麻。
2.3 基础语法:三种核心写法一看就会
Design.md 的源文件就是标准 Markdown,额外支持三类约定写法,学起来成本极低。
第一类是页面头信息(front-matter),放在每个.md文件最开头,用---包裹,定义页面的布局、标题和引用的主题:
--- layout: app title: 登录页面 theme: team-collab ---第二类是设计令牌,用键值对描述风格变量。基础写法很简单:
tokens: color.primary: "#4F6EF7" font.size.base: "14px" radius.card: "12px"第三类是组件调用。用@component 组件名开头,缩进列表里写参数:
@component button - variant: primary - size: large - text: 立即登录这三种写法覆盖了原型设计的 90% 场景。先不要急着学花哨的语法,把这三类写熟,已经足够支撑一个完整的高保真原型。
3. 实操记录:从零为协同工具项目搭一套风格化原型
3.1 第一步:把品牌色和字体写进设计令牌
模拟项目 X 是一个团队协同工具,主打高效、清爽、可信赖。我先把产品风格翻译成视觉语言:主色用偏冷静的蓝色#4F6EF7,辅助色用绿色表示成功、橙色表示警告、红色表示危险;背景用非常浅的灰#F7F8FC,卡片用纯白;字体使用系统字体栈,保证在不同设备上都有良好的中文显示效果。
这些决策写进tokens/base.yaml就成了这样:
tokens: color.primary: "#4F6EF7" color.primary.hover: "#3B5CDB" color.success: "#16A34A" color.warning: "#D97706" color.danger: "#DC2626" color.bg: "#F7F8FC" color.surface: "#FFFFFF" color.text.primary: "#1F2937" color.text.secondary: "#6B7280" font.family: "-apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif" font.size.base: "14px" font.size.sm: "12px" font.size.title: "20px" radius.sm: "6px" radius.md: "10px" radius.lg: "16px" space.sm: "8px" space.md: "16px" space.lg: "24px" shadow.card: "0 1px 3px rgba(0, 0, 0, 0.08)"圆角、间距、阴影这些看似不起眼的变量,恰恰是产品风格一致性的关键。很多原型看起来“业余”,不是因为内容不对,而是间距忽大忽小、圆角不统一。令牌化以后,这些问题从机制上就被消除了。
3.2 第二步:用组件块拼装首页
有了令牌,下一步是用组件块拼装页面。以模拟项目 X 的首页任务看板为例,先定义任务卡片组件components/task-card.md:
@component task-card - title: 撰写需求文档 - owner: 林晓 - status: 进行中 - priority: 高 - due: 12月20日页面文件pages/index.md里只需要引用组件,并补充页面特有的标题、说明和布局描述:
--- layout: app title: 任务看板 theme: team-collab --- # 任务看板 > 页面目标:让成员一眼看清本周所有任务的状态分布。 @component app-header - user: 林晓 - project: 模拟项目 X - notice: 3 ## 进行中的任务 @component task-card - title: 撰写需求文档 - owner: 林晓 - status: 进行中 - priority: 高 - due: 12月20日 @component task-card - title: 设计评审材料 - owner: 阿哲 - status: 进行中 - priority: 中 - due: 12月22日 ## 已完成 @component task-card - title: 用户访谈提纲 - owner: 小满 - status: 已完成 - priority: 高 - due: 12月18日渲染器会根据status参数自动填充对应颜色和图标样式,我不需要手动关心颜色值,令牌已经帮我做了映射。这种“只描述业务内容,不管视觉细节”的写法,让我可以把注意力集中在信息架构和任务优先级上。
3.3 第三步:给状态与跳转加上交互描述
静态页面无法完成流程验证,所以 Design.md 支持在组件上追加状态与跳转描述。我希望点击任务卡片能进入详情页,于是这样写:
@component task-card - title: 撰写需求文档 - owner: 林晓 - status: 进行中 - priority: 高 - due: 12月20日 - link: task-detail.md渲染后,卡片整块变成可点击区域,点击会跳转到任务详情页。对于需要多状态展示的组件,我还用区块区分默认态、悬停态和按下态:
@component button - variant: primary - size: large - text: 创建任务 @state hover - text: 创建任务 - shadow: 0 2px 8px rgba(79, 110, 247, 0.3)@state块里的属性会覆盖默认样式,让原型模拟出真实的反馈感。评审时别人不会再把“这个按钮点下去有没有变化”当成疑问,因为原型本身已经展示了。
3.4 第四步:多页面装配与导出评审包
原型不可能只有一个页面。我在pages目录里依次建立了登录、首页、任务详情、成员管理等页面,并用link参数把它们串成完整流程。
全部写完后,执行构建命令:
design-md build输出目录默认是dist,里面是纯静态 HTML、CSS 和少量 JavaScript。我把整个dist目录压缩成一个压缩包,发到评审群里,同事解压后双击index.html就能走通全流程。部署到内部服务器也很快,一个静态站点服务就够了。
这一步的价值在于消除了评审的“工具门槛”。不需要账号、不需要安装软件、不需要学习按钮位置,原型就是一个任何人都能打开的网页。
4. 让原型真正“符合产品风格”的进阶手法
4.1 状态完整性:空态、加载态与错误态一个不少
很多原型只画“理想状态”,列表有数据、表单填写正确、页面加载完毕。评审的时候大家都说感觉不错,可一到真实使用,遇到没有数据、加载缓慢、接口报错,产品体验立刻拉胯。真正专业的高保真原型,一定会把空态、加载态、错误态画全。
我在模拟项目 X 里为任务列表定义了三种状态。空态组件写得很明确:
@component empty-state - icon: inbox - title: 暂无任务 - description: 创建一个任务,团队协作从这里开始。 - action: 创建任务 - action-link: create-task.md加载态则通过@state块模拟骨架屏效果。这样在评审时,我可以直接演示“第一次进入项目”“接口返回慢”“查询无结果”三类场景,让产品和开发提前对齐异常情况下的文案和交互。状态完整,才是风格完整;只画理想页面的原型,本质上还没脱离线框图思维。
4.2 间距、栅格与对齐:风格一致性的隐藏开关
颜色和字体是最容易被感知的风格元素,但间距和栅格才是保持页面“呼吸感”的关键。很多团队的视觉稿单页看很漂亮,合在一起却显得乱,问题大多出在间距体系不统一。
Design.md 的令牌把间距收敛成space.sm、space.md、space.lg等有限的档位。我给自己定了一条规矩:页面里不要出现令牌之外的任何间距数值。8 像素、16 像素、24 像素、32 像素,宁可少用几档,也不要临时拍脑袋加一个 14 像素。
栅格方面,我在pages/index.md里用布局描述指定两列或三列排布:
@layout grid - columns: 2 - gap: space.md这样任务卡片会自动按两列排布,间距使用令牌中的space.md。任何一边想加宽间距,只需要改令牌,页面整体都会同步变化。这种全局联动能力,是手工调整画布的高保真原型难以做到的。
4.3 评审不翻车:演示前的三级走查清单
我踩过不少评审现场翻车的坑,后来总结出一套走查清单,每次演示前按顺序过一遍。
第一级查内容完整性:每个页面的标题、说明、按钮文案是否符合当前需求文档,有没有遗留的占位文字。第二级查交互闭环:所有可点击的组件都必须有明确的跳转目标,不能出现点了没反应的死链接;表单的提交、取消、返回三种路径都要能走通。第三级查风格一致性:主色、圆角、间距是否严格来自令牌,有没有在页面里写死特殊值。
清单听起来简单,但真正执行起来非常有效。第三次为模拟项目 X 做演示时,我按照清单走查,发现一个空态页面的按钮跳转指错了文件。如果没查出来,评审现场演示到那里就会断掉,会直接拉低整场评审的可信度。
5. 踩坑实录:组件、样式和协作问题的排查
5.1 组件渲染与预期不一致
我第一次用 Design.md 时,最常遇到“组件渲染出来跟我想象的不一样”的情况。比如我希望按钮是主色,渲染出来却是灰色的。排查思路很直接:先看组件参数名有没有拼错,再看组件模板里引用的令牌名是否存在,最后检查是否在页面级覆盖了组件样式。
有一次任务卡片的优先级标签始终显示默认灰色,查了半天发现是priority的取值写成了“高优先级”三个字,而组件模板里只认“高”“中”“低”这样的单字。问题不在渲染器,在我的数据取值。这类问题告诉我:组件的参数协议要先定清楚,写在文档里,再开始批量写页面。
5.2 样式优先级迷思
Design.md 的样式优先级规则是:组件默认样式低于页面内联样式,页面内联样式低于组件@state中的覆盖样式。理解这个顺序之后,大部分“改不动样式”的问题都能解决。
我遇到过的情况是,在页面上用内联样式调整了卡片间距,结果悬停状态的阴影覆盖又把间距带了回去,看起来像样式没生效。后来我把状态里的覆盖属性限定为只改交互反馈相关字段,比如阴影、背景色,不去碰布局属性。这算是一条经验教训:不要在状态块里写布局属性,状态块只负责“反馈”和“变化”,不负责“位置”。
5.3 多人协作时的冲突处理
Markdown 文件天然适合 Git 协作,但团队多人同时改一个页面文件,仍然会产生合并冲突。我第一次带实习生一起搭原型时,两个人同时改了pages/index.md的顶部导航区,结果 Git 报冲突。
解决方式分两种。如果是同一文件的同一区块冲突,那就需要人工合并,看清楚两边保留了谁的内容、放弃了谁的内容。更干净的办法是拆分文件:把每个页面里的组件拆到components目录,页面文件只做引用和排序,这样多人各自负责不同组件时,冲突概率会大幅降低。我把这个规则定为团队约定:谁改组件,谁改页面引用,职责要分开。
5.4 常见问题速查表
我把平时遇到的高频问题整理成一个速查表,分享出来:
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 组件显示为纯文本 | 组件名拼写错误 | 检查@component行是否与文件名一致 |
| 颜色值不生效 | 令牌名不存在 | 在tokens/base.yaml中核对键值 |
| 点击组件无跳转 | link参数指向了不存在的文件 | 核对目标.md文件是否存在 |
| 两个页面风格不同 | 页面引用了不同主题 | 统一theme参数 |
| 保存后页面无变化 | 本地服务未监听该目录 | 重启design-md serve |
| 构建出来的静态页图片丢失 | 图片使用了绝对路径 | 改用相对路径assets/xxx.png |
这张表让团队新成员可以自行排查几个最基础的问题,大大减少了重复提问。做工具类项目,沉淀一份问题速查表比口头解答的效率高得多。
6. 边界与扩展:什么场景我会换回图形工具
6.1 图形工具依然占优势的场景
虽然 Design.md 很好用,但我不会无脑推荐它替代所有工具。在最早期、最发散的需求探索阶段,我仍然会打开画布类工具。原因很简单:当我还不知道信息架构长什么样的时候,最快的方案是画一堆卡片贴来贴去,而不是雕琢 Markdown 的层级和组件参数。
在需要精细视觉设计、复杂动效设计的时候,图形工具也更合适。Design.md 的渲染器再灵活,也替代不了动效软件和专业的视觉排版工具。我现在的选择是“混合流程”:发散阶段用图形工具,明确方向后立刻转入 Design.md 做高保真原型,视觉细节的最终打磨再回到视觉工具完成。
这个切换点通常发生在信息架构定稿的那一刻。一旦页面清单确定、核心流程画完,就是迁入 Design.md 的最佳时机。它能把已经达成的结构共识,快速固化成一套风格统一、可点击、可评审的完整原型。
6.2 与设计系统的后续接力
Design.md 的价值不止停留在原型阶段。因为设计令牌本身就是结构化的键值对,它可以直接生成前端代码里的 CSS 变量,甚至导出成设计系统工具能识别的 JSON 文件。
我在模拟项目 X 里做过一次尝试:把tokens/base.yaml里的颜色、间距、圆角直接生成为 CSS 变量文件,前端同学拿过去稍作整理,就成了项目全局样式的基础。原型里的按钮、卡片组件,也被改写成前端的真实组件。这样原型和线上产品不再是“一边是画稿、一边是代码”的脱节状态,而是同一套设计资产在不同阶段的不同形态。
这个接力过程会省掉非常多的重复沟通。开发不再问“这个按钮悬停该用什么色”,因为原型和设计系统里的定义完全一致;设计师也不用反复导出标注图,因为所有数值都是结构化、可追溯的。
6.3 一点个人心得
做了几年产品设计,我越来越相信一句话:工具应该迁就工作流,而不是让人迁就工具。Design.md 真正打动我的,不是它把原型变成了“写代码”,而是它让设计过程变得可以被记录、被比较、被回溯。每次修改都有迹可循,每个风格决策都有据可查,条目化的工作方式让团队更透明、更高效。
如果你也想试试,我建议别一上来就追求完整规范,先找一个两周内要评审的小项目,搭建一个只有三个页面的原型。跑通流程、感受到文本驱动的好处之后,再逐步扩展组件库和令牌系统。不要一开始就追求完美,先把脏活跑顺,比什么都划算。