根本原因是未定义@media print规则,导致浏览器按屏幕样式打印;必须在所有屏幕样式后单独声明@media print,对iframe、表格、textarea及绝对定位元素需针对性处理。

打印时内容被截断,根本原因是没写 @media print
直接调用 window.print() 但没配 @media print 规则,浏览器就按屏幕样式硬打——浮动、flex、固定定位全照搬,overflow: hidden 的容器内容直接消失,position: absolute 元素偏移出纸张边界。这不是兼容性问题,是漏写了唯一生效入口。
必须满足两个前提:
-
@media print { }块得放在所有屏幕样式之后,不能嵌套在其他媒体查询里 - 涉及打印的样式(比如隐藏导航栏)必须加
!important,否则容易被通用规则覆盖 - 如果页面含
<iframe>,父页的@media print不会穿透生效,需在 iframe 内单独定义
table 打印跨页断裂,光写 page-break-inside: avoid 不够
给 <table> 加 page-break-inside: avoid 在 Chrome/Firefox 中对小表格有效,但长表格仍会被劈开——因为浏览器对 <tr> 的分页控制极弱,且默认不重复 <thead>。
真正起效的组合是:
立即学习“前端免费学习笔记(深入)”;
-
thead { display: table-header-group; }—— 让表头在每页顶部自动重现 -
tbody tr { page-break-inside: avoid; page-break-after: auto; }—— 阻止单行被拆,同时避免强制分页导致空白页 -
table { width: 100%; box-sizing: border-box; }—— 避免边框或 padding 溢出纸张
textarea 打印内容换行错乱或被截断
打印时 <textarea> 显示异常,不是宽度设小了,而是它被卡在窄列里(比如 <td class="input-column">),white-space: normal 强制折行,原始换行符和空格全丢。
别试图拉宽列或改 min-width,纸张尺寸和分页算法会让这种硬调失效。稳妥做法是绕过渲染本身:
- 用
onInput实时把值同步到父容器的data-replicated-value属性 - 在
@media print中用::after伪元素读取该属性,配合white-space: pre-wrap渲染 - 用 CSS Grid 将
<textarea>和伪元素叠放,打印时display: none原生控件,只显示文本层
绝对定位元素在打印中消失或偏移
position: absolute 元素打印时“不见了”或跑到纸张外,大概率是因为它的父容器没设 position: relative。浏览器找不到定位上下文,就回退到初始包含块(通常是带默认 margin: 8px 的 <body>),而打印时 <body> 和 @page 区域并不对齐。
修复只需两步:
- 给绝对定位元素的**直接父容器**加
position: relative和box-sizing: border-box - 在
@media print中统一重置:* { float: none !important; position: static !important; },再对需要保留定位的元素单独声明
复杂点在于:打印引擎对 position: sticky 和 flex 子项的绝对定位支持极差,能不用就不用;@page { margin: 0 } 必须配合 body { margin: 0; padding: 0; },但仅此还不够——定位锚点缺失才是多数偏移的根源。



















