小票打印需解决浏览器默认样式、分页控制、纸宽适配、空白页/截断、字体嵌入缺失五大问题;须用@media print重置样式、禁用背景与flex、显式设宽高、用等宽字体并关闭抗锯齿。
小票打印不是简单地把 HTML 丢给 window.print() 就能出效果的,核心问题在于:浏览器默认样式、分页控制、物理打印机纸宽适配、空白页/截断、字体嵌入缺失——这五点不处理,打出来大概率是错位、多页、字被切、字号发虚。
@media print 强制重置所有样式浏览器打印视图会继承页面 CSS,但小票纸宽通常只有 58mm 或 80mm(对应 CSS 中约 width: 384px 或 576px),而默认 body margin、font-size、line-height 全都不适配。不重置就会留白边、文字挤成一团或换行错乱。
实操建议:
<style> 中写 @media print { * { margin: 0; padding: 0; font-size: 12px; line-height: 1.4; },全局清空再重建body { width: 384px; margin: 0 auto; }(按热敏打印机实际像素宽调整)* { background: transparent !important; },热敏机不支持彩色/灰度,且会浪费碳带flex 或 grid 布局——部分旧款驱动不识别,改用 display: table 或纯 div + float
window.print() 前必须调用 focus() 和隐藏非打印元素Chrome 和 Edge 在 iframe 或弹窗中调用 window.print() 时,若窗口未获得焦点,可能静默失败或弹出空对话框;Safari 则对 display: none 元素的打印支持不稳定。
立即学习“前端免费学习笔记(深入)”;
实操建议:
window.focus();,确保当前窗口激活class="receipt",其他区域加 class="no-print"
@media print 中写 .no-print { display: none !important; },比内联 style="display:none" 更可靠visibility: hidden —— 它仍占布局空间,可能导致分页错位小票内容长度不确定,但热敏打印机要求“一单一页”,不能出现 page-break-after: always 导致中间空页,也不能让内容撑开导致第二页只打半行。
实操建议:
@media print 中强制关闭分页:html, body { height: auto !important; page-break-after: avoid !important; }
height: fit-content(兼容性差)或更稳妥的 min-height: 100vh 配合 overflow: visible
white-space: nowrap 防止被断在两行(例如 ¥199.00 被切成 ¥199. 和 00)font-smoothing 降级热敏打印机 DPI 低(常见 203dpi),自定义 Web 字体(如 WOFF)几乎必然发虚、笔画粘连;iOS Safari 还会忽略 font-smoothing 设置。
实操建议:
font-family: "Courier New", monospace;,等宽+无衬线,字符对齐稳定-webkit-font-smoothing: none; 和 -moz-osx-font-smoothing: grayscale;,关掉抗锯齿(热敏纸不需要)font-weight: bold —— 多数热敏机靠加粗算法模拟,易糊成黑块;改用双字符或 text-shadow: 1px 0 #000 模拟px(如 12px),不用 rem 或 em,避免缩放干扰真正难的不是写出能打印的 HTML,而是同一份代码在 Windows Chrome、macOS Safari、安卓 WebView 里都打出一致的小票——驱动差异、DPI 解析、CSS 支持度全都不一样。每次换打印机型号,至少要重测三遍:空白页、金额对齐、末行是否被裁掉。