做产品经理这几年,我前后换了四款原型工具,从Axure到Figma又绕回HTML,身边不少同事觉得我有点折腾。但如果你试过用HTML/CSS/JS直接搭一版高保真原型,再把它推到GitHub上生成一个公网链接发给开发、发给客户、贴在PRD第一行,大概率就回不去了。这篇文章不聊高深前端技术,只讲我如何从IDE环境搭建开始,把一个HTML原型变成一个随手可访问的线上页面,完整覆盖编辑器选型、项目结构、交互写法、Git管理、GitHub Pages公网部署,以及实战中踩过的坑。想用代码做原型的产品经理、独立开发者、小团队技术负责人,都可以直接照着走一遍。
这套流程最大的价值,是让原型不再是一个需要装软件才能打开的专属文件,而是一个谁都能在浏览器里打开的页面。开发想看交互逻辑可以直接F12看代码,客户想看效果只需要一个链接,团队想评审只需要打开同一个地址。它让“产品想法”和“最终实现”之间的距离缩短了一大截。下面我会从最关键的问题开始聊。
1. 为什么产品经理要写HTML原型?这不是返祖,是找对工具
1.1 原型工具的瓶颈
几乎所有产品经理都经历过工具选择的纠结。Axure很强大,可以做出复杂交互和变量判断,但每次评审前都要导出HTML,导出的包体积大、打开慢,而且改一版就要重新导一次。Figma在视觉协作上是目前的天花板,但产品经理在Figma里画原型,总觉得是在“画图”而不是在“做产品”,尤其当你要表达表单校验、列表筛选、状态流转这类真实业务逻辑时,Figma的原型能力反而显得笨重。
HTML原型在解决这些痛点时非常直接:原型本身就是网页,开发打开浏览器就能看到最终效果,还能直接查看DOM结构、CSS样式,很多界面层的沟通成本直接消失。你不需要额外导出,不需要让对方装什么软件,不需要担心版本对不对,一个链接就是最新版。而且HTML是文本格式,天然适合用Git管理,每次改动都有记录,可以随时回溯和对比。
1.2 HTML原型的真实价值
很多人以为HTML原型就是“拿代码画线框图”,这是误解。它真正的价值在交付链路里。交付给开发时,开发可以直接按F12看样式和结构,能更准确地估算工作量,也知道哪些组件可以直接复用;交付给客户时,一个公网链接发过去,不用管对方是Windows还是Mac,也不用管有没有装Axure;交付给团队评审时,把GitHub上的提交记录一拉,能清楚看到原型从V1到V5的每一处变化,再也不用来回比对“哪个版本才是最新”。
还有一个容易忽略的隐藏价值:产品经理开始写HTML后,和前端工程师就有了共同语言。评审会上讨论“这个按钮用主色还是次色”,你可以直接打开CSS变量说“这里改一个变量,全局都会变”;开发说“这个交互成本高”,你可以直接指着一行JS说“其实就是一个显示隐藏的逻辑”。这种沟通效率,是传统原型工具完全给不了的。
1.3 这套流程适合谁
不是所有产品经理都适合这套路线,要分场景。如果做纯C端营销页,或者对视觉创意要求很高的项目,Figma仍然是更好的选择。但如果你经常要交付“能点、能跳转、能看逻辑”的功能原型,而且需要在多人之间流转、需要持续迭代版本,HTML原型就非常值得尝试。尤其是B端产品,页面信息密度高、逻辑复杂,用传统工具搭出来的原型很难还原真实的信息排布,而HTML可以做到和最终界面几乎一样的布局。
这套流程的门槛并不高:会基本的HTML标签、CSS选择器、一点点JavaScript语法就够了,不需要会框架。如果完全零基础,可以先照着一个静态页面模板写,慢慢加交互。团队里有前端工程师更好,他们稍微指导一下,你很快就能上手。我的建议是别把它当成“学习编程”,而是当成“换一种更精确的画原型方式”。一旦换了视角,学习速度会快很多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 本地IDE选型:把VS Code调教成原型工作台
2.1 IDE怎么选
先解释一下IDE这个词。IDE叫集成开发环境,简单理解就是“写代码的工作台”。写HTML/CSS/JS其实不需要重型IDE,但我依然推荐用VS Code,因为它的插件生态能让写原型这个过程变得非常顺手。免费、跨平台、启动速度快,是目前最主流的选择。你也可以用Sublime Text或者WebStorm,但除非你已经很习惯某一款,否则没必要折腾。
VS Code对产品经理最友好的地方,是它把很多常用功能做成了“开箱即用+插件补全”。比如写HTML标签时,输入一个标签名再按Tab,会自动补全开闭标签;写CSS时,选择器名称会有智能提示;配合Git插件,提交代码、查看修改记录都可以在图形界面里完成。这些能力能大幅减少产品经理学工具的挫败感,让你把精力集中在原型内容上。
2.2 几个必装插件与配置
安装VS Code之后,我建议先装以下几款插件,都是实际体验中很有用的:
- Live Server:本地起一个开发服务器,文件修改后浏览器自动刷新,是原型开发必备。
- Prettier - Code formatter:保存时自动格式化代码,让HTML结构保持一致,不会乱成一团。
- HTML CSS Support:写class属性时自动补全CSS中的类名,能少敲很多字。
- Auto Rename Tag:修改开标签时自动同步修改闭合标签,避免漏改。
- GitLens:在代码行内显示Git提交记录,适合想了解原型版本变化的时候用。
插件装完后,建议打开“文件 -> 自动保存”。产品经理写原型时注意力应该集中在内容和交互逻辑上,不要被“手动保存”这件事打断。自动保存配合Live Server,每次修改后浏览器马上刷新,体验接近Figma的实时预览。这个工作方式一开始可能觉得不习惯,但用一天之后基本就离不开了。
2.3 从零建立原型项目目录
不要一上来就在一个HTML文件里堆所有东西,建议从一开始就按下面的结构组织项目:
text复制prototype/
├── index.html
├── css/
│ └── style.css
├── js/
│ └── app.js
└── assets/
└── images/
index.html是入口页面,css/style.css放全局样式,js/app.js放交互逻辑,assets/images放图片和图标。如果页面很多,可以在根目录下增加pages文件夹,放二级页面。文件名统一用小写英文,不要用中文,也不要用空格,避免部署到GitHub Pages后出现路径编码问题。目录结构清晰还有一个好处:开发拿到你的原型仓库后,可以很快找到对应模块的HTML和样式文件,沟通效率会高很多。
基础HTML骨架先不用写得太复杂,时刻记住“原型不是生产代码”。只要结构清晰、语义明确、方便维护就够了。如果你的页面越来越多,再考虑拆组件,否则在原型阶段过早抽象反而浪费时间。
2.4 Live Server本地预览
装好Live Server后,在index.html文件上右键,选择“Open with Live Server”,浏览器会自动打开类似http://127.0.0.1:5500的地址。之后每次修改代码保存,浏览器都会自动刷新。这个操作彻底解决了传统“写完代码手动刷新页面”的麻烦,也让产品经理能够在第一时间看到改动后的效果。
我习惯在本地把原型整体流程点通,再推送到GitHub。如果本地都没走通就急着部署,结果往往是提交一次、失败一次,把Git提交记录弄得非常难看。使用Live Server还有一个好处:可以配合浏览器开发者工具里的设备模式,模拟手机屏幕查看效果。虽然产品经理不用像前端那样专业,但会看Console报错、会看Network里的资源加载情况,已经能解决大部分原型问题。
3. 用HTML/CSS/JS把原型画出来:产品经理要懂到什么程度
3.1 用语义化标签搭页面骨架
写HTML原型时,我建议先别纠结像素和圆角,第一次先把页面整体结构按“信息架构”分块。这就像画线框图时先画区块,只是把图形换成了HTML标签。比如页面顶部是导航,用<header>;侧边栏菜单用<nav>;核心内容区用<main>;各个业务模块用<section>;底部说明用<footer>。每个区块都加一行注释,写清楚“这里是什么”,例如:
html复制<main>
<!-- 审批列表区域 -->
<section class="approval-list">
<h2>待我审批</h2>
<!-- 这里将来放审批卡片 -->
</section>
<!-- 统计概览区域 -->
<section class="stats-overview">
<div class="stat-card">今日申请数:12</div>
</section>
</main>
这样的好处是,所有看代码的人(包括你自己)都能一眼看出这个页面的信息优先级。后续加CSS时,目标非常明确;开发review原型时,也能快速理解产品业务结构。同时,语义化标签对搜索引擎和屏幕阅读器也更友好,虽然原型阶段不一定考虑这些,但养成好习惯总没错。
3.2 CSS变量让视觉迭代更轻松
样式是原型高保真的关键,但不需要从头写一套复杂设计系统。用CSS变量定义基础规范,就足够模拟大部分设计语言。比如在style.css顶部写:
css复制:root {
--primary: #2f6fed;
--danger: #e5484d;
--success: #30a46c;
--bg-color: #f7f8fa;
--text-color: #1a1a1a;
--radius: 8px;
--space: 16px;
}
.btn-primary {
background: var(--primary);
border: none;
border-radius: var(--radius);
padding: calc(var(--space) / 2) var(--space);
color: #fff;
cursor: pointer;
}
这套写法的好处是“全局可调”。评审时客户说“主色能不能柔和一点”,你只需要改--primary这一行,页面里所有按钮、链接、选中态都会跟着变;产品规范调整了圆角,改--radius即可。在原型阶段,这样一套变量足以模拟设计规范,同时让你在评审会上具备强大的“现场修改能力”。比拿着一张图片去设计软件里改颜色靠谱得多。
3.3 用轻量JS模拟交互动效
产品经理写HTML原型,不需要把交互做得像正式系统那么复杂,但至少要能说服评审方“这个流程能走通”。我建议只用原生JavaScript完成三类常用交互:页面切换、弹窗显隐、表单校验。
页面切换可以用一个简单的data-page绑定方式。给每个按钮加data-target属性,点击时隐藏所有页面区块,只显示目标区块。代码大致是:
javascript复制function switchPage(pageId) {
document.querySelectorAll('.page').forEach(function (page) {
page.style.display = 'none';
});
document.getElementById(pageId).style.display = 'block';
}
弹窗显隐同样简单,点击“新增”按钮时,把遮罩层和弹窗从display:none切换成flex。表单校验则可以用input事件动态显示错误提示,比如手机号输入不满11位时,下面出现红色提示文字。这样就够了。用这些轻量交互去模拟真实操作流程,比在原型工具里设置繁琐的交互状态要直观得多,也更容易让前端理解最终实现逻辑。
3.4 原型阶段要不要做响应式
这个问题取决于你的产品形态。如果做的是桌面端后台系统,响应式可以先不做,只要保证内容不横向溢出就行。如果产品以移动端为主,建议至少加上viewport标签和简单的媒体查询:
html复制<meta name="viewport" content="width=device-width, initial-scale=1.0">
css复制@media (max-width: 768px) {
.card {
width: 100%;
margin-bottom: 12px;
}
}
移动端原型不需要把每个断点都做完美,但至少要让老板和客户在手机上打开链接时,不会第一眼就认为“这个页面坏了”。根据我的经验,移动端原型把字号、按钮宽度、卡片间距这三样调好,基本就能正常看了。过度设计响应式会让原型开发时间成倍增加,这是产品经理写原型时最容易陷入的陷阱。
4. 把原型推进GitHub:版本管理从第一天开始
4.1 为什么压缩包传达方式是万恶之源
我见过太多团队用微信传原型压缩包,文件名从“原型V1.zip”到“原型V2-最终版.zip”再到“原型V2-最终版-修改2.zip”,最后根本分不清哪一版是最新。Git解决的就是这个问题:每次修改都有提交记录,可以在GitHub上查看任意版本的差异对比;哪一版出问题了可以随时回滚;多人协作时不会互相覆盖。GitHub还提供了Issues和Projects,可以把原型评审中的反馈转成issue,指派给负责人,跟踪解决状态,形成从“提问题”到“关闭问题”的闭环。
对产品经理来说,掌握Git不需要变成专家,只需要理解“提交记录”“分支”“合并”这几个核心概念,就足以让原型管理上一个台阶。而且HTML原型是纯静态文件,几乎不会像代码项目那样出现复杂冲突,所以学起来完全没有心理负担。
4.2 第一次提交并推送仓库
在本地安装Git后,需要先配置用户名和邮箱,否则提交会失败:
bash复制git config --global user.name "你的名字"
git config --global user.email "你@example.com"
然后在项目根目录打开终端,执行初始化、提交、关联远程仓库并推送:
bash复制git init
git add .
git commit -m "chore: 初始化HTML原型"
git branch -M main
git remote add origin https://github.com/你的用户名/仓库名.git
git push -u origin main
执行完最后一条命令后,刷新GitHub仓库页面,就能看到原型文件已经被推上去了。这里建议在仓库根目录加一个.gitignore文件,用来忽略不需要提交的文件,比如.DS_Store、node_modules等。原型阶段虽然没有这些依赖,但提前养成好习惯,以后扩展项目时会省很多事。
4.3 分支与评审:多人协作也能玩转
如果只是一个人维护原型,可以全部提交在main分支。但如果团队里有多个产品经理,或者需要试验一些比较激进的新交互,建议用分支管理:main分支作为稳定版,每次准备给团队评审时再合并;想要尝试新方案时,开一个feature/xxx分支,改完确认没问题再合入。
基本命令只需要记住几个:
bash复制git checkout -b feature/dark-mode
git add .
git commit -m "feat: 尝试暗色模式"
git push origin feature/dark-mode
然后到GitHub上发起Pull Request,请前端或设计同事评审。这个流程听上去有点“工程化”,但实际操作起来反而比传统方式轻。因为原型是静态文件,合并时基本不会冲突,你只需要按照“开分支、提交、推送、合并”这个节奏走就行。评审过程中产生的讨论,也会自然沉淀在PR里,比微信群里的语音消息好查一百倍。
5. GitHub Pages公网部署:三步拿到可访问链接
5.1 部署前需要确认的路径问题
部署到GitHub Pages之前,最重要的一步是检查资源引用路径。如果你的仓库名是你的用户名.github.io,那么访问地址就是https://你的用户名.github.io/;如果是普通仓库名,比如prototype-demo,那么访问地址是https://你的用户名.github.io/prototype-demo/。这时候在HTML里写资源的路径就非常关键。
我见过太多人部署后页面打开是纯HTML,但样式和图片全丢了,原因就是路径写成了绝对路径。比如在本地开发时写href="/css/style.css",部署后会从https://你的用户名.github.io/css/style.css去找文件,这个路径当然不存在,因为你的项目实际是在/prototype-demo/下面。正确写法是在所有HTML中,把资源引用改成相对路径:
html复制<link rel="stylesheet" href="./css/style.css">
<script src="./js/app.js" defer></script>
<img src="./assets/images/logo.png" alt="logo">
页面之间跳转也一样,写成href="./detail.html",而不是href="/detail.html"。这个坑几乎所有人都会踩一次,部署前全局搜索一下/css、/js、/assets这些开头带斜杠的路径,可以省掉很多后续排查时间。
5.2 用Settings页面手动部署
如果只是想快速发布一个原型评审链接,可以不用任何自动化,直接在GitHub仓库页面操作。进入仓库的Settings,找到左侧的Pages,在Source处选择Deploy from a branch,分支选main,目录选/root,然后保存。等一到两分钟,GitHub会给你一个类似https://你的用户名.github.io/仓库名/的地址,打开就是你的原型页面。
这种方式适合原型更新频率不高、只是发一个一次性评审链接的场景。缺点是每次更新原型后,都要手动进Settings等待部署,稍微有点繁琐。如果原型迭代周期短,一天要改好几版,建议直接用下面提到的GitHub Actions自动部署。
5.3 用GitHub Actions实现自动发布
我目前更推荐用GitHub Actions,因为只要推送到main分支,部署就会自动触发,不需要再进Pages设置页面。在仓库根目录创建.github/workflows/deploy.yml文件,内容如下:
yaml复制name: Deploy to GitHub Pages
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/upload-pages-artifact@v3
with:
path: .
- uses: actions/deploy-pages@v4
保存并推送这个文件之后,去Settings -> Pages,把Source改为GitHub Actions。以后每次执行git push到main,GitHub就会运行这个工作流,自动把当前仓库根目录下的静态文件发布到Pages。部署状态可以到仓库的Actions标签页查看,黄色是进行中,绿色对勾是成功,红色是失败。这套自动化的好处是,你只需要关注提交代码,发布是顺便完成的。
5.4 部署后常见问题排查
部署完成后如果页面有问题,不要慌,绝大多数都是以下几个原因:
| 问题现象 | 可能原因 | 排查方法 |
|---|---|---|
| 打开页面404 | 分支设置不对,或者仓库名不对 | 检查Settings里的Pages配置,确认分支和目录 |
| 页面有HTML但没有样式 | 资源引用了绝对路径 | 打开浏览器F12看Network里CSS文件的请求路径 |
| 图片裂开 | 文件名大小写或中文路径 | 文件统一用小写英文名,路径保持一致 |
| 修改后线上没更新 | GitHub Pages缓存或Actions没有成功 | 查看Actions运行状态,一般需要等待1-2分钟 |
| 点击子页面刷新后404 | 使用了history路由 | 原型阶段建议用hash路由,例如#/detail |
其中“有HTML但没有样式”是最高频的问题。打开浏览器开发者工具,切到Network面板,刷新页面,看CSS文件的请求地址到底指向哪里,很快就能定位。如果发现路径指向了根目录而不是项目子目录,就需要回HTML里把路径改成相对路径。这个排查过程并不难,但非常锻炼产品经理的调试能力。
6. 实操经验与避坑清单
6.1 路径问题是第一坑
我前面强调过路径问题,但还是想单独拎出来再说一次。很多产品经理第一次用GitHub Pages部署时,会在本地打开HTML一切正常,部署到线上后样式全丢,第一反应是“GitHub是不是有问题”。其实绝大多数时候都是路径问题。HTML里的相对路径和绝对路径,在本地和线上解析规则不一样,尤其是部署在项目子目录时。
我的习惯是,在项目初始化的时候就把所有资源引用写成相对路径,哪怕是首页也写./css/style.css而不是直接写css/style.css。这样虽然看起来多一个点,但在部署环节能规避掉最麻烦的问题。同时也建议所有文件名都小写,避免在Linux服务器上因为大小写不匹配导致404。这个习惯从第一天开始坚持,后面会非常省心。
6.2 别在原型里使用太新的前端语法
产品经理写原型,最容易犯的另一个错是“看到什么新语法就往上用”。我曾经在原型里用了ES2020的可选链操作符?.,本地Chrome跑得很欢,结果评审会上有位领导用了一台旧电脑打开原型,整个页面白屏。原因是他的浏览器不支持新语法。原型是用来给团队和客户看的,不是你实验新技术的试验田。
建议在原型阶段尽量使用兼容性好的基础JavaScript写法,比如直接用function而不是箭头函数,尽量不用?.和Array.flat这类比较新的API。等将来真的需要构建流程、转译语法时,再交给前端团队去处理。同样,不要为了追求所谓的技术栈而引入npm包或框架,静态HTML原型最重要的是稳定、可访问、可演示。
6.3 用真实内容填充,效果好过Lorem ipsum
画原型的时候填一堆“文字文字文字”或者“Lorem ipsum”,是产品经理最容易踩的坑。评审方对假内容的敏感度很低,但如果换成真实业务字段,讨论深度立刻不一样。比如审批列表里,你放上真实的“员工姓名、请假类型、提交时间、审批状态”,开发会立刻开始想这些数据从哪里来、字段怎么对接;业务方也会在看到真实数据后,提出更具体的问题。
为了更方便地填充真实内容,可以在app.js里维护一个mock数据数组,然后用循环渲染到页面上。例如:
javascript复制var approvals = [
{ name: '张伟', type: '事假', time: '2024-06-12 09:30', status: '待审批' },
{ name: '李娜', type: '年假', time: '2024-06-12 10:10', status: '待审批' }
];
var listHtml = approvals.map(function (item) {
return '<div class="approval-item">' +
'<span>' + item.name + '</span>' +
'<span>' + item.type + '</span>' +
'<span>' + item.time + '</span>' +
'<span>' + item.status + '</span>' +
'</div>';
}).join('');
document.getElementById('approval-list').innerHTML = listHtml;
这样后续想换数据,只需要改数组里的内容,页面会自动更新。真实内容能让评审会的讨论更有价值,也能让原型更接近最终的线上体验。
6.4 把部署链接放进需求文档
这个习惯我坚持了很久。所有PRD、需求文档、周报里,只要涉及原型,我都附上GitHub Pages的链接,并标注“当前版本提交号:abc1234”。这样一来,评审会开始前大家打开的是同一个链接,不会再出现“我看的怎么是旧版”的尴尬。如果需求有变更,我更新原型后会把新的提交链接发到群里,同时在GitHub仓库里打个Tag记一个版本号。
这个工作流看起来轻描淡写,但长期坚持下来,能显著减少团队内的沟通成本。产品经理不再需要一遍遍发压缩包,也不再需要回答“你有没有发最新版”这种问题。链接本身就是版本,Git提交记录就是变更说明,这是传统原型工具很难做到的事情。
6.5 后续可以扩展的方向
等你熟悉了这套流程,可以往几个方向继续完善。一是引入Tailwind CSS这样的原子CSS框架,写样式会更快,但需要在流程里引入构建步骤;二是把原型里的mock数据替换成真实接口,让原型变成一个“半成品前端”,这样开发可以基于它继续开发,但要注意跨域问题;三是为原型仓库配一个README,写清楚访问地址、操作手册和更新日志,方便新同事快速上手;四是如果团队已经有设计系统,把CSS变量对齐设计系统变量,让原型自动跟随主视觉更新。
这些扩展都不是必须的,可以根据团队阶段和协作需要慢慢加。关键是先把“HTML原型 + IDE + GitHub公网部署”这条主线跑通。跑通之后,你会发现原来做一个可交付、可评审、可追溯的原型,并没有想象中那么复杂。
最后再分享一个我自己的小习惯。每次原型部署完,我会先自己用手机访问一次链接,从首页开始把整个流程点一遍,再发给别人。因为有些问题在电脑上看起来正常,手机上打开就是另一回事。花三分钟做这轮“发布前自检”,能省掉后续很多“怎么打不开啊”“样式乱了”的对话。HTML原型的价值,不在于让你变成前端工程师,而在于让产品想法在浏览器里快速活起来,并且能被版本化、被分享、被持续迭代。希望你的第一个HTML原型,也能顺利完成从IDE到公网的这次跳跃。
