前几天一位做运营的朋友发来一份用文档编辑器排好的简历说打印出来第二页只剩孤零零两行字怎么调都压不回去。我打开文件一看整个版式是用文本框和表格一层层拼出来的牵一发而动全身。我半开玩笑说了一句要不你直接用HTML重写一份吧。她第一反应是简历还能用HTML写能而且用HTML写简历这件事价值远不止于“交付一份PDF”这么简单。HTML简历本质上是用网页技术完成信息排版。你写的内容是纯文本样式交给CSS全权负责两者互不干扰。最终你可以把它导出成一份排版稳定的PDF也可以让它变成一个在线可访问的页面甚至可以放进代码仓库里跟踪每一次修改。如果你正在准备求职想把自己的信息展示做得更精细又或者你只是个前端新手想找一个小而完整的练手项目这篇文章都适合你。下面我会从为什么选它、怎么设计、如何实操、怎么导出、怎么避坑五个角度完整讲一遍所有代码都是我实际用过的方案你可以直接抄去改。1. 为什么用HTML写简历而不是文档编辑器或模板网站1.1 简历的本质是信息排版HTML天然适合这件事先想一个问题简历到底是什么它不是你全部经历的罗列而是把“我是谁、我做过什么、我能做什么”压缩进一页纸的信息排版。好的简历内容和样式是分离的内容决定你说什么样式决定别人看着舒不舒服。文档编辑器最大的问题恰恰是内容和样式缠在一起。你挪一下图片文字跟着跳你改一个字号整个段落全部错位你换一台电脑打开字体、间距、分页全部变了。HTML加CSS的组合天生就是为“内容与样式分离”设计的写出来的结构清清楚楚改起来也放心。有人会说模板网站不是更方便吗填几个框就能生成一份简历。但模板网站有两个很难绕开的痛点一是所有模板都长得像同一个流水线出来的HR一天收两百份简历撞模板的概率比想象中高得多二是你想加一个模块、调整两栏宽度、改一个响应式布局模板网站往往做不到或者要付费解锁。自己用HTML写等于把版面控制权完全拿回自己手里想要什么效果都能调出来。1.2 HTML简历的核心优势可控、可版本、可复用我坚持用HTML写简历的原因归纳起来有三个。第一是可控。字号、行高、间距、分页位置都能精确到毫米级尤其是导出PDF后每一页在哪断、每段内容怎么留白我能完全预测。第二是可版本化。HTML是纯文本文件我可以顺手放进版本控制工具里。每次改简历都留下一个提交记录什么时候改过哪一行、删了哪个项目一目了然以后投不同的公司还能基于同一份源文件快速生成不同侧重点的版本互不干扰。第三是可复用。今天做简历明天做个人主页、作品集、项目文档本质上都是同一套技能写成一次长期受益。还有一点常被忽略HTML简历最终也可以被搜索引擎收录。如果你希望别人通过公开渠道找到你的履历一份语义化良好的HTML页面比一份PDF更友好也更容易被检索到。当然公开意味着隐私风险这个我在后面专门讲。1.3 那些年我踩过的格式坑说多了都是泪我自己也曾经用文档编辑器排过简历踩过的坑说出来都够写一篇事故报告。第一坑是表格撑破。为了做两栏布局我用表格套表格结果字号一调右侧栏被挤得乱七八糟打印出来边界对不齐。第二坑是版本错乱。电脑里存了“简历终版”“简历最终版”“简历真的最终版2”投出去的还是旧版面试官问起一个已经删掉的老项目场面非常尴尬。第三坑是打开乱码和字体替换。换台电脑打开中文字体变成默认宋体行距全变原来一页刚好放下现在多出半页空白。这些问题在HTML里几乎都不存在源文件统一用UTF-8编码字体栈由CSS控制分页逻辑由打印样式统管稳定性高得多。2. 动手前先想清楚简历信息架构与模块设计2.1 一份合格简历必备的五个信息模块别一上来就写代码先想清楚简历上到底放哪些内容。以我筛简历的经验一份有效简历最少要有五个模块基本信息、工作经历、项目经历、技能栈、教育背景。基本信息放在最上面包含姓名、现任岗位、联系方式、个人主页等工作经历按时间倒序排列写清楚公司、职位、起止时间和核心职责项目经历挑两三个最能体现你能力的项目写明你的角色、做的内容和量化结果技能栈不要写“精通各种技术”而是写具体的技术名称和熟练程度教育背景放在靠后位置除非你是应届生否则它只是补充信息。模块顺序不是固定的。如果你的求职方向是技术岗项目经历应该提到教育背景前面如果你的经历比较偏向管理或业务工作经历要放在最显眼的位置。同一个HTML文件里模块顺序可以随时调整这也是用代码写简历的好处——改结构比在文档里拖动整个段落要可靠得多。2.2 用语义化标签搭建简历骨架而不是一堆div写HTML简历最容易犯的错就是从头到尾全是div。div本身没有任何语义浏览器、搜索引擎、读屏软件都不知道它里面装的是什么。更好的做法是用语义化标签整个简历最外层是body里面用header放姓名和联系方式用section分模块用article装一条具体的工作或项目经历用footer放一句可选的说明。这样哪怕CSS加载失败浏览器也能把内容按合理顺序展示出来读屏软件也能准确跳过装饰性内容。层级上也要注意h1是姓名不是“个人简历”四个字。你想想一个页面最重要的标题当然是“你是谁”而不是“简历”这种人人都知道的重复信息。每个模块标题用h2比如“工作经历”“项目经历”。工作经历里的公司名和职位名可以用h3这样整份简历的信息层级像目录一样清晰。列表项用ul加li联系方式之间也建议用ul方便阅读器逐条朗读。2.3 内容取舍简历是给筛选者看的不是给你自己看的写简历内容的时候要时刻记住一个原则先给筛选者看再给面试官看。筛选者花在一份简历上的时间通常是十几秒这十几秒里他们只看几个关键词岗位匹配度、技能命中词、项目成果、时间是否连续。所以你的经历描述里动词开头、结果导向是最基本的写法。比如“负责XX系统开发”不如“搭建XX系统支撑日均XX请求”有力量“参与需求分析”不如“梳理需求推动XX功能按期上线”有说服力。还有两个容易被忽略的细节。第一是时间格式要统一要么全写“2023.06 - 2024.09”要么全写“2023年6月 - 2024年9月”不要混用。不统一的时间格式会给人一种做事不细心的印象。第二是照片放不放。除非招聘岗位明确要求否则不一定放如果放就放一张正式、清晰、近期的证件照不要在简历里放大头自拍或者生活照。3. 核心实操从零手写一份HTML简历3.1 一版可以直接用的HTML骨架下面这份HTML骨架是我一直在用的基础版本两栏布局、语义化标签、结构清晰你可以直接复制到本地改。文件名建议用index.html后续方便部署。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title张三 - 前端开发工程师简历/title link relstylesheet hrefstyle.css /head body div classpage header classheader h1张三/h1 p classtitle前端开发工程师 / 5年经验/p ul classcontact li电话138-0000-0000/li li邮箱zhangsanexample.com/li li个人主页https://example.com/li li所在城市某市/li /ul /header div classcontainer aside classsidebar section classsection h2技能栈/h2 ul liHTML / CSS/li liJavaScript / TypeScript/li liReact / Vue/li liNode.js/li liGit / 工程化/li /ul /section section classsection h2教育背景/h2 h3某大学/h3 p计算机科学与技术 · 本科/p p2013.09 - 2017.06/p /section /aside main classmain section classsection h2工作经历/h2 article classitem h3某科技公司 · 前端工程师/h3 p classmeta2021.07 - 至今/p ul li负责核心管理后台的前端架构升级代码量压缩约三成构建时间减少一半。/li li推动组件库落地业务复用率明显提升跨团队协作效率改善。/li /ul /article article classitem h3某互联网公司 · 前端开发/h3 p classmeta2019.03 - 2021.06/p ul li参与多个移动端H5项目开发完成活动页与数据看板等核心模块。/li /ul /article /section section classsection h2项目经历/h2 article classitem h3跨平台数据看板系统/h3 p classmeta2022.02 - 2023.01 · 项目负责人/p ul li基于前端技术栈独立搭建可视化数据看板支持多端适配与定时刷新。/li li负责整体设计、进度拆分与最终交付项目按期上线并稳定运行。/li /ul /article /section /main /div /div /body /html这个结构有几个值得注意的点。div.page是整份简历的容器后面所有页面尺寸控制都挂在它上面div.container用来分左右两栏。两个section分别放侧栏和主体内容侧栏适合放技能栈、教育背景这类相对静态的信息主体放工作经历和项目经历。article.item代表一条具体经历语义上就是一个完整的、可独立存在的内容块样式上可以整体控制边距也方便在打印时避免被拆到两页。3.2 CSS布局两栏简历怎么排最稳两栏布局是简历里最常用的版式左侧窄栏放技能和教育背景右侧宽栏放工作经历和项目经历。实现方式我推荐Flexbox简单、稳、不用考虑老浏览器兼容问题。看下面这份样式注意注释里标出来的关键点。* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, PingFang SC, Noto Sans CJK SC, sans-serif; color: #333; background-color: #f0f0f0; line-height: 1.6; } .page { width: 210mm; min-height: 297mm; margin: 20px auto; padding: 14mm 16mm; background: #fff; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); } .header { border-bottom: 2px solid #2c3e50; padding-bottom: 8px; margin-bottom: 12px; } .header h1 { font-size: 26pt; color: #2c3e50; } .header .title { font-size: 12pt; color: #555; } .contact { display: flex; flex-wrap: wrap; gap: 8px 24px; list-style: none; font-size: 9.5pt; margin-top: 6px; } .container { display: flex; gap: 20px; } .sidebar { flex: 0 0 34%; } .main { flex: 1 1 66%; } .section { margin-bottom: 14px; } .section h2 { font-size: 12.5pt; border-left: 3px solid #2c3e50; padding-left: 8px; margin-bottom: 6px; } .item { margin-bottom: 12px; break-inside: avoid; } .item h3 { font-size: 11pt; color: #222; } .item .meta { font-size: 9pt; color: #777; } .item ul { margin-top: 4px; padding-left: 18px; } .item li { font-size: 9.5pt; margin-bottom: 2px; } media (max-width: 720px) { .page { width: auto; min-height: auto; margin: 0; padding: 16px; box-shadow: none; } .container { flex-direction: column; } }为什么用Flexbox而不是浮动浮动布局要清浮动两栏高度不一致时还容易错位Flexbox一行代码就能解决左右排列和等高问题。侧栏宽度我用flex: 0 0 34%表示不伸缩、固定占父容器34%宽度右侧主体自动占据剩余空间。文字大小我特意用了pt而不是px因为pt是物理单位和打印尺寸对应关系更明确你写10pt就是10磅屏幕上看着和纸张上的大小基本一致。line-height用1.6这个行高对中文阅读来说比较舒服不会显得太挤也不会太散。配色上我建议主体用深灰和黑色点缀色只留一个。上面代码里的深蓝灰#2c3e50用于姓名、模块标题的左边框和页头分隔线面积占比很小但能让整页看起来有主次。千万不要把简历做成彩虹色大面积彩色在打印时既费墨也容易显得不专业。3.3 细节打磨字号、间距与可读性的一点点经验很多简历质量差不是内容问题而是阅读感受问题。字号方面我的经验值是姓名24到28磅模块标题12到14磅正文9到10.5磅辅助信息8.5到9.5磅。这个比例在A4纸上有清晰的视觉层级一眼看过去先看到姓名然后是模块标题最后才是具体内容。间距方面最常犯的毛病是“到处都很挤”。模块之间至少留12到16磅的距离段落内行高不要低于1.4。还有一个小技巧模块标题下沿加一点留白让标题和内容之间的关联更紧密而不是让标题悬在一堆文字上面。另外简历正文不要用两端对齐中文两端对齐容易出现“字与字之间被拉出大空隙”的水面感左对齐最自然。颜色上点缀色全篇不超过一种。如果拿不准就用黑白灰加一个深色强调色永远不出错。最后记得把无意义的装饰元素删掉比如多余的图标、动态特效、花哨边框。简历的第一属性是信息传达效率不是视觉炫技。4. 进阶打印导出PDF与响应式的完整方案4.1 让简历在A4纸上完美呈现打印样式适配屏幕上看着再好看最终交出去的PDF如果分页错了一切都白费。为了让一份HTML在A4纸上按你的预期呈现需要专门的打印样式。做法是在CSS文件末尾加一段media print把屏幕上用于装饰的阴影、留白、背景色全部去掉并以A4纸的尺寸为准重新定义页面。page { size: A4; margin: 0; } media print { body { background: #fff; } .page { width: 210mm; min-height: 297mm; margin: 0; padding: 14mm 16mm; box-shadow: none; background: #fff; } .section, .item { break-inside: avoid; } }关键点有三个。第一page { size: A4; margin: 0; }表示整张纸的外边距为0所有留白都由.page的padding控制。这样你不用担心浏览器默认页边距和你的padding叠加造成内容偏移。第二.item加break-inside: avoid意思是“尽量别把一条工作经历拆到两页”这是防止“第二页只有半行字”这种翻车现场的核心设置。第三屏幕上的box-shadow一定要在打印时去掉否则有些浏览器会把阴影打印成一团灰块极其难看。4.2 导出PDF的正确姿势与常见翻车现场HTML简历做完以后导PDF我推荐直接用浏览器的打印功能操作路径是打开HTML文件按快捷键调出打印预览在目标打印机里选择“另存为PDF”然后做三个关键设置去掉“页眉和页脚”、勾选“背景图形”、纸张大小选A4、边距选“无”。不同浏览器的菜单措辞略有差异但核心就这几项。说来也好笑我见过不少HTML简历线上预览时非常漂亮导出来的PDF却惨不忍睹。多数原因是漏了背景图形选项页面上有背景色或者强调色边框但导出PDF时浏览器默认不打印背景于是所有配色全部消失只剩黑字白底。所以你导出前一定要检查预览区域看到底色和边框都在再点保存。如果你有自动化交付的需求还想更进一步可以用无头浏览器脚本去控制打印。写一段脚本把index.html载入无头浏览器调用打印接口输出PDF这种方式适合需要频繁生成多个版本的场景。不过日常求职递简历手动导出完全够用没必要为了简历专门搭一套构建工具。导出之后还有一个习惯值得养成用PDF阅读器把每一页都翻一遍尤其是检查页脚有没有多余的页码、页眉有没有出现网页标题。如果网页标题是“张三-前端开发工程师简历”而你没有关掉页眉那页面上方会多出一行和你正文重复的文字非常违和。4.3 手机端查看与在线投递响应式要怎么做现在很多简历不是先打印而是直接在手机、平板上被打开。如果你打算把简历做成在线网页响应式就是绕不开的问题。我通常的做法是桌面端是标准A4两栏窄屏比如720像素以下自动切成一栏侧栏内容移到主体内容上方变成“先个人资料、再技能、再经历”的自然阅读顺序。上面CSS代码里的媒体查询已经实现了这个效果你直接把浏览器窗口拖窄就能看到变化。在线发布到一个可公开访问的地址时有几个点要格外小心。第一如果页面会被搜索引擎收录而你又不想让某类信息被全文抓走可以考虑不把电话、邮箱写在纯文本里用图片或其他方式替代但替代方案会影响可用性所以要先想清楚这个简历是给谁看的。第二页面上的外部链接都要加上安全属性避免被当作跳转漏洞利用。第三发布前检一遍页面里有没有不该公开的信息比如内部项目的测试地址、服务器IP、公司内部系统截图。这些内容一旦上线撤下来要花很多精力。5. 常见问题与排查技巧实录5.1 中文乱码与字符编码HTML简历最常见、也最让人崩溃的问题就是中文乱码。原因绝大多数只有一个meta charsetUTF-8没写或者写成了别的编码又或者文本编辑器默认用GBK保存文件。解决办法很简单第一head里务必写上meta charsetUTF-8第二文件保存时选择UTF-8编码如果编辑器有“UTF-8无BOM”选项优先选它第三避免从文档编辑器复制内容时带进奇怪的隐藏格式字符。乱码还有一个隐蔽来源是字体缺失。你的电脑上有某个漂亮的字体但换一台电脑打开同一个HTML浏览器找不到该字体只能回退到系统默认字体看起来就像“排版全乱”了。解决方法是把字体栈写完整比如在font-family里依次列出不同系统的常见中文字体没有第一个就用第二个依次回退最终必然落到系统无衬线字体上。5.2 打印分页断裂、二维码失效、图标不显示、图片模糊分页断裂前面提过核心解决办法是给section和item加break-inside: avoid。这里再补充一个技巧如果某一条经历特别长实在避免不了跨页你可以把它的标题和内容拆开让标题单独保持在本页底部内容从下一页开始阅读起来不会那么突兀。二维码在简历上很常见用来放个人主页或作品集链接。失效的常见原因有三个二维码内容链接太长、生成的二维码容错率太低、打印尺寸太小。我的建议是链接尽量短容错率选中等或高打印后二维码宽度至少20毫米并且放在不会被订书机订到的位置。图标不显示的问题多半是因为你用了图标字体库但导出PDF或换设备后字体加载失败。最稳妥的办法是内联SVG——直接把SVG代码写进HTML不依赖任何外部文件显示永远不会丢。图片模糊的问题是因为屏幕分辨率和打印分辨率不一样。网页按72到96dpi显示而打印通常需要300dpi。所以简历里如果放照片或项目截图源文件应当足够大不要拿一张400像素宽的图片硬撑到半个版面打印出来全是锯齿。如果只是简单的头像我甚至建议直接不发照片省掉很多麻烦。现象常见原因解决方案中文乱码缺字符编码声明或文件保存编码不对加meta charsetUTF-8并以UTF-8保存打印第二页只剩一行未设置打印分页规则给section和item加break-inside: avoidPDF缺少背景色和边框浏览器默认不打印背景图形打印设置里勾选“背景图形”图标变成方块外部图标字体库加载失败改用内联SVG或系统字体图片打印模糊图片分辨率不足使用足够大的高清图或减少图片使用页面出现网页标题打印页眉未关闭在打印设置中去掉页眉页脚5.3 隐私保护与文件管理发送前必须做的三件事最后说一个很多人都会忽略的环节。写HTML简历时文件里可能残留编辑器注释、临时调试代码、旧版本联系方式甚至还有你不小心写进去的内部项目敏感信息。发送之前请至少做三件事。第一导出PDF后检查一次文档属性里的标题、作者等信息是否可接受。如果你不希望PDF里带着内部测试文件的名称或路径建议用一个干净的浏览器环境导出或导出后在阅读器里清除文档属性。第二文件名规范成“姓名-应聘岗位-简历-日期.pdf”不要用final_final_v2.pdf这种命名HR下载下来都不知道该存什么。第三发送前打开源文件按CtrlF全局搜索一遍电话号码、旧地址、原公司内网地址等关键词确认没有多余信息。在线发布的版本更要考虑是否公开真实联系方式必要时对电话号码做脱敏处理。我个人在实际操作中的体会是把简历当成一个小型前端项目来维护反而比当一份“文档”更省心。每次大版本更新我会把index.html和导出的PDF一起保存文件名带上日期投递不同岗位时只改内容模块的顺序和描述重点CSS基本不动。这个习惯坚持下来再也没有出现过“投出去的简历是旧版”这种尴尬。最后再分享一个小技巧在HTML文件的head注释里写一行“最后修改时间”和版本号导出PDF后无论这份文件流转到哪里只要打开源代码就能确认版本HR如果打回来问“你投的是哪一版”你也能立刻答出来。别小看这个细节危急时刻它能帮你省下大把解释时间。
阅读完成 · 觉得有帮助?