边框和圆角是文档排版中最常用也最容易忽视的细节。一张表格没有边框,数据挤成一团难以阅读;一个卡片没有圆角,页面显得生硬;而边框属性写错一处,整页可能直接错位。dompdf.js 对边框与圆角提供完整支持:四边独立边框、实线虚线点线样式、单角圆角与椭圆圆角都能按标准 CSS 渲染,且边框以矢量线条写入 PDF,任意缩放依然清晰。本文从边框的基本属性讲起,覆盖简写与单边写法、边框样式在 PDF 中的表现差异、圆角的各种写法(固定值、百分比、椭圆),结合表格、卡片、标签等真实场景给出完整代码示例,最后整理常见坑点与排查方法,帮助你快速掌握这套基础而关键的样式能力,让导出的文档经得起放大查看和打印检验。文章最后还总结了边框相关的排查清单,遇到问题可以直接对照定位,减少调试时间。
边框由宽度、样式、颜色三个维度构成,对应 border-width、border-style、border-color 三个属性,也可以合并成简写:border: 1px solid #333。dompdf.js 完整支持这套体系,宽度支持 px、pt、em 等单位,颜色支持与颜色文章一致的全套色值写法,与浏览器规则一致。
四边可以分别控制:border-top、border-right、border-bottom、border-left 单独设置某一边,适合只画下划线的标题或只加左侧强调线的引用块;更精细的写法是逐维拆开,比如 border-top-width: 2px,灵活度与浏览器完全一致。
边框在 PDF 中按矢量线条绘制,这是与位图方案的本质区别:放大 200% 线条依然锐利,打印到纸张上也不会发虚。因此可以放心使用细边框(0.5px 到 1px),不需要为了打印清晰而刻意加粗,文档细节更精致。
边框宽度与内容区的计算也需要留意:默认情况下边框宽度计入元素总尺寸,width 设置的是包含边框在内的宽度;模板里需要精确控制版式时,可以借助 box-sizing: border-box 统一计算规则,避免反复微调尺寸。
边框颜色同样支持透明与渐变替代方案:需要渐变边框效果时,可以用背景渐变加内层底色模拟,或者使用 border-image 语法;大多数场景下多层边框加背景的组合更稳定,渲染结果也更容易预期。
border-style 支持 solid、dashed、dotted、double 等取值。solid 实线最常用,适合表格、卡片等结构性边框;dashed 虚线适合强调区域或待填写区;dotted 点线适合弱分隔;double 双线适合正式文件的标题下划线,样式选择与网页一致。
表格是边框的高频场景,border-collapse: collapse 与 separate 的差异必须理解:collapse 合并相邻单元格的边框,避免出现双倍粗细的边线,是报表模板的默认选择;separate 保留独立边框,配合 border-spacing 可以做错落的分隔效果,适合特殊版式。
透明边框是一个经典技巧:border: 1px solid transparent 可以为元素预留边框空间,配合 hover 等状态切换时内容不会跳动。在 PDF 模板里同样适用,比如为卡片预留选中态边框位,保证版式稳定,不会因为样式切换而错位。
虚线点线的间距与密度由引擎按标准渲染,不同浏览器可能存在细微差异,但 PDF 输出以引擎实现为准;如果对虚线效果有严格要求,可以先用浏览器预览对比,再调整线宽与颜色,找到最接近预期的组合。
表格边框之外,区块边框也是常见需求:卡片、提示框、引用块的边框粗细与颜色应当与表格体系协调,建议模板里统一定义边框变量,比如细线用 1px 浅灰、强调线用 2px 深色,一套规范贯穿整个文档。
border-radius 支持统一圆角、四角分别设置与椭圆圆角三种写法:border-radius: 8px 四角统一;border-radius: 8px 4px 表示对角组合;border-radius: 10px 20px 30px 40px 按左上、右上、右下、左下顺序分别设置,控制粒度与浏览器一致。
椭圆圆角写法是 border-radius: 10px 20px,水平半径与垂直半径不同,可以做出胶囊、跑道形等特殊形状;百分比圆角则相对元素尺寸计算,border-radius: 50% 配合正方形元素就能得到正圆形,适合头像、徽章、状态点等场景。
圆角会裁剪背景与边框,配合渐变背景可以做出立体卡片质感;圆角区域内的背景色会被正确裁剪,不会溢出到圆角外。需要注意的是,圆角值不要超过元素尺寸的一半,否则按浏览器规范会被钳制,实际渲染以钳制后的值为准。
圆角与边框宽度的配合也值得注意:边框较宽时,圆角会沿边框内侧平滑过渡,视觉效果更柔和;细边框加小圆角则显得精致干练,两者的组合选择取决于文档的整体风格,保持统一即可。
圆形元素是圆角的高级应用:头像、状态点、徽章都可以用 50% 圆角实现,配合边框与背景色形成完整的视觉单元;圆形内放置文字时注意留白,文字过多会被裁剪,建议控制字数或增大元素尺寸。
import { DomPDF } from 'dompdf.js';
const html = `
<style>
.card {
border: 1px solid #d5dbe3;
border-radius: 12px;
padding: 20px;
background-color: #fbfcfe;
}
.badge {
display: inline-block;
border: 1px solid #27ae60;
border-radius: 999px;
padding: 2px 10px;
font-size: 12px;
color: #27ae60;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #b8c2cc;
padding: 8px;
text-align: left;
}
th { background-color: #2c3e50; color: #fff; }
.divider { border-bottom: 2px solid #3498db; }
</style>
<div class='card'>
<h2 class='divider'>订单明细</h2>
<p><span class='badge'>已发货</span></p>
<table>
<tr><th>商品</th><th>数量</th><th>金额</th></tr>
<tr><td>机械键盘</td><td>1</td><td>¥ 399</td></tr>
<tr><td>鼠标垫</td><td>2</td><td>¥ 59</td></tr>
</table>
</div>`;
const pdf = new DomPDF({ format: 'A4', margin: '20mm' });
pdf.addPage(html, { format: 'A4' });
pdf.save('borders-demo.pdf');
表格边框是报表的核心:表头深色底加白字,表体细边框加浅色隔行,汇总行加粗上边框,层次分明;卡片边框配合圆角与浅色背景形成内容分区,适合报价单、产品卡、统计面板;标签胶囊圆角配合状态色,适合订单状态、审核进度等场景。
分隔线是容易被忽略的细节:标题下方用 2px 实线或双线,区块之间用浅色 1px 线,比整块边框更轻盈;避免在同一页面混用过多不同粗细的线条,统一的线条体系能让文档显得更专业,视觉噪音更少。
边框也可以参与布局:用 border-bottom 实现伪列对齐,用透明边框预留空间,用 0 宽边框做基线对齐。理解边框占据布局空间的特性,在计算宽度时记得把边框宽度计入,避免容器溢出或内容被挤到下一页。
发票与合同场景中,边框常用于区分条款区域与签名区:条款区用细边框分隔,签名区用虚线框提示填写位置,配合圆角让整体更友好;边框体系一旦确定,整份模板的视觉语言就成型了,后续新增内容只需套用现有样式。
打印场景下边框还有实际功能:深色边框在双面打印时可能透印到背面,建议大面积深色边框控制在 1-2px,或者改用浅色大面积填充加深色细边框的组合,兼顾美观与打印成本。
Q: 表格边框出现双倍粗细?A: 这是相邻单元格边框叠加的经典现象,给 table 设置 border-collapse: collapse 即可合并;若仍需 separate 模式,可以通过只给一边设置边框来控制视觉粗细,避免双线出现。
Q: 圆角在 PDF 里显示为直角?A: 检查是否给元素设置了显式的高度与宽度,或圆角值是否被其他属性覆盖;百分比圆角依赖元素尺寸,尺寸未确定时可能退化为直角,固定尺寸的容器最稳定。
Q: 边框颜色透明后背景露出来了?A: 透明边框只隐藏线条,不裁剪背景;若需要圆角裁剪背景,请确认 background-color 与 border-radius 写在同一个元素上,不要在子元素上单独设置背景色。
Q: 0.5px 边框打印时消失?A: 细边框在部分打印设备上可能被舍入,建议正文边框至少 1px,强调边框 2px;也可以用浅色加粗代替极细线,兼顾打印清晰度与视觉轻盈感。
还有一个隐蔽问题:圆角元素的背景图片或渐变若未正确裁剪,会在圆角外露出直角边角;确保背景与圆角在同一元素上声明,必要时配合 overflow 属性控制裁剪范围,输出即可保持圆角轮廓干净。
排查边框问题时建议分步验证:先只保留 border 声明观察输出,再逐步加回其他属性,很快就能定位是哪个属性影响了边框渲染;也可以在浏览器里用相同 CSS 预览对比,帮助判断是引擎差异还是写法问题。
下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:
这是由 dompdf.js 渲染的示例 PDF 内容。