小票打印失败主因是html结构未做打印专用隔离;须用独立扁平容器动态注入内容,禁用flex/grid/伪元素,统一用px字号、monospace字体及table-cell布局。

直接用 window.print() 打小票,90% 的失败都出在 HTML 结构没做「打印专用隔离」——不是样式错,是结构本身被浏览器默认渲染逻辑拖垮。
为什么不能复用页面主结构打小票
主页面的 <header></header>、<nav></nav>、<footer></footer>、JS 动态插入的广告位或弹窗遮罩,在 @media print 下仍参与布局计算;热敏打印机纸宽仅 384px(58mm)或 576px(80mm),而普通页面最小宽度常超 1200px,导致内容被强制缩放、换行错乱、文字被截断。
- 不要把小票塞进现有页面 DOM 树里,哪怕加了
display: none - 打印前必须生成一个独立、扁平、无嵌套容器,例如:
<div id="receipt-print-area"></div> - 所有小票内容用 JS 动态注入该容器,而非靠 CSS 隐藏其他区域
- 避免使用
<table> 嵌套超过两层,旧款热敏驱动对 <code>colspan渲染不稳定必须禁用的 HTML 特性与替代写法
热敏打印机驱动(尤其 Star、Epson、Zijiang 系列)对现代 HTML/CSS 支持有限:不识别
flex、grid、position: absolute、伪元素::before/::after,且对em、rem单位换算错误率高。- 用
display: table-cell替代flex实现左右对齐(如“商品名”左对齐、“金额”右对齐) - 字号统一用
px,推荐font-size: 12px,禁用font-size: 1rem - 行高固定为
line-height: 1.4,避免line-height: normal导致高度浮动 - 分隔线用
<div style="height: 1px; background: #000;"></div>,不用border-bottom - 中文字符间不加空格,避免 Safari 打印时额外换行
window.print()调用前的三个硬性检查点Chrome/Edge/Safari 在不同上下文下调用
window.print()表现差异极大,不检查就调用,轻则空白页,重则静默失败。- 必须先执行
window.focus(),尤其在 iframe 或 modal 中触发打印时 - 确保目标容器已挂载到
document.body,且不在display: none父容器内(Safari 对此极其敏感) - 调用前移除所有非必要 script 标签和事件监听器,防止 JS 错误中断打印流程
字体与空白控制:热敏机最易忽略的两个坑
热敏打印机没有抗锯齿,也不支持 Web Font 加载,若用系统默认中文字体(如 Windows 的微软雅黑、macOS 的 PingFang),在小字号下会发虚、粘连、缺笔画;同时,HTML 默认保留文本节点间的空白符,导致小票出现意外空行。
- 强制指定等宽字体:
font-family: "Courier New", monospace;,所有设备都能 fallback 到清晰像素级渲染 - 给小票容器加
white-space: nowrap,再对需要换行的字段(如商品描述)单独设white-space: normal - 用
<pre class="brush:php;toolbar:false;"></pre>包裹纯文本段落(如商户名称、地址),避免浏览器自动合并空白 - 禁用
text-rendering: optimizeLegibility,它会让热敏机把汉字笔画渲染成模糊灰块
小票结构越简单,兼容性越稳;与其花时间调试 flex 布局在不同驱动下的表现,不如用 table-cell + 固定 px + monospace 字体搭出可预测的输出。真正难的不是写 HTML,而是让浏览器「放弃智能」,老老实实按你写的像素值画出来。
- 用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











