具有绝对位置的 HTML 打印

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10902686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 00:51:57  来源:igfitidea点击:

HTML print with absolute postitions

htmlcssprinting

提问by dronus

Is it possible to print a HTML page with truly absolute positioned elements to paper? It seems all browsers are doing a big mess here. It is easy to define a body by absolute units (eg. cm) and place elements by position: absoluteinside. However, every browser seem to try to make it impossible to print such a page. FF for example is adding print margins, even when printing to a PDF on linux despite 0-margin page settings. Chrome seems to shrink the page in every case. So how to print something with absolute positioning, eg. paper form fields, markings etc.? Have I overlooked something?

是否可以将具有真正绝对定位元素的 HTML 页面打印到纸上?似乎所有浏览器都在这里搞得一团糟。很容易用绝对单位(例如厘米)定义主体并按position: absolute内部放置元素。然而,每个浏览器似乎都试图让打印这样的页面变得不可能。例如,FF 正在添加打印边距,即使在 linux 上打印到 PDF 时也是如此,尽管页面设置为 0 边距。Chrome 似乎在任何情况下都会缩小页面。那么如何打印具有绝对定位的东西,例如。纸质表格字段、标记等?我是否忽略了什么?

回答by Zeta

Sadly, the CSS3 Module: Paged Mediaallows all this to happen. This are the rules concerning pages which are too big:

遗憾的是,CSS3 模块:分页媒体允许这一切发生。这是关于页面太大的规则:

3.3.3. Rendering page boxes that do not fit a page sheet

If a page box does not match the target page sheet dimensions, the user agent MAY choose (in order of preference) to:

  • Render the page box at the indicated size on a larger page sheet.
  • Rotate the page box 90° if this will make the page box fit the page sheet.
  • Scale the page box to fit the page sheet. (There is no requirement to maintain the aspect ratio of the page or of any elements on the page when scaling; however, preservation of the aspect ratio is preferred.) [done by Chrome]
  • Reformat the page contents, including 'spilling' onto other page sheets. [done by many other or older browsers]
  • Clip overflowed content (least preferred).

The user agent shouldconsult the user before performing these operations.

3.3.4. Positioning the page box on the sheet

When the page box is smaller than the page size, the user agent shouldcenter the page box on the sheet since this will align double-sided pages and avoid accidental loss of information that is printed near the edge of the sheet.

3.3.3. 渲染不适合页面的页面框

如果页面框与目标页面尺寸不匹配,用户代理可以选择(按优先顺序):

  • 在较大的页面上以指定的大小呈现页面框。
  • 如果这将使页框适合页纸,请将页框旋转 90°。
  • 缩放页面框以适合页面。(缩放时不需要保持页面或页面上任何元素的纵横比;但是,最好保留纵横比。)[由 Chrome 完成]
  • 重新格式化页面内容,包括“溢出”到其他页面上。[由许多其他或更旧的浏览器完成]
  • 剪辑溢出的内容(最不喜欢)。

用户代理在执行这些操作之前应该咨询用户。

3.3.4. 在工作表上定位页面框

当页面框小于页面大小时,用户代理应该将页面框放在工作表上的中心,因为这将对齐双面页面并避免意外丢失靠近工作表边缘打印的信息。

And this is the rule which breaks all your positioned stuff:

这是打破你所有positioned内容的规则:

3.7. Content outside the page box

[...] Also, when boxes are positioned absolutely, they MAY end up in "inconvenient" locations. For example, images MAY be placed on the edge of the page box. Similarly when boxes use fixed or relative positioning, they MAY also end up outside of the page box.

A specification for the exact formatting of such elements lies outside the scope of this document. However, we recommend that authors and user agents observe the following general principles concerning content outside the page box:

  • User agents SHOULD avoid generating a large number of empty page boxes to honor the positioning of elements (e.g., you don't want to print 100 blank pages). Note, however, that generating a small number of empty page boxes MAY be necessary to honor the 'left' and 'right' values for 'page-break-before' and 'page-break-after'.
  • Authors SHOULD not position elements in inconvenient locations just to avoid rendering them. Instead:
    • To suppress box generation entirely, set the 'display' property to 'none'.
    • To make a box invisible, set the 'visibility' property.
  • User agents MAY handle boxes positioned outside the page box in several ways, including discarding them or creating page boxes for them at the end of the document.

3.7. 页面框外的内容

[...] 此外,当盒子被绝对定位时,它们可能最终会出现在“不方便”的位置。例如,图像可以放置在页面框的边缘。类似地,当框使用固定或相对定位时,它们也可能最终位于页面框之外。

此类元素的确切格式规范超出了本文档的范围。但是,我们建议作者和用户代理遵守以下有关页面框外内容的一般原则:

  • 用户代理应该避免生成大量的空页面框来尊重元素的定位(例如,你不想打印 100 个空白页面)。但是,请注意,可能需要生成少量的空页面框以支持“page-break-before”和“page-break-after”的“left”和“right”值。
  • 作者不应该为了避免渲染它们而将元素放置在不方便的位置。反而:
    • 要完全抑制框生成,请将“display”属性设置为“none”。
    • 要使框不可见,请设置 'visibility' 属性。
  • 用户代理可以通过多种方式处理位于页面框外的框,包括丢弃它们或在文档末尾为它们创建页面框。

Have a look at the second paragraph of section 3.7: A specification for the exact formatting of such elements lies outside the scope of this document.Since there is no other document and no other guideline then the general principle following this paragraph, every browser can do whatever it want.

查看第 3.7 节的第二段:此类元素的确切格式规范超出了本文档的范围。既然没有其他文档,也没有其他指南,那么遵循本段的一般原则,每个浏览器都可以为所欲为。

It's one of the flaws that are currently in this CSS3 module. However, I think those flaws cannot be removed by a CSS4 or revised CSS3 module, as the variety of possible stylesheets and resulting layouts is too huge too cover. Also note a little footnote given in CSS Print Profile:

这是当前此 CSS3 模块中的缺陷之一。但是,我认为 CSS4 或修改后的 CSS3 模块无法消除这些缺陷,因为可能的样式表和由此产生的布局的种类太多太多。还要注意CSS Print Profile 中给出的一个小脚注

? The printer MAY ignore positioned elements that are placed on the page before the position of the current element in the normal flow.

? 打印机可以忽略在正常流中当前元素位置之前放置在页面上的定位元素。

So it's basically not possible to create the same effect in every browser. As for the time being, the only possible way to achieve a portable document is to create a PDF with a third-party application or via a PDF printer and your most favorite browser. Every other way is bound to fail as long as either the W3C's recommendations aren't strict or the browser vendors implement whatever they want.

所以基本上不可能在每个浏览器中都创建相同的效果。就目前而言,实现便携式文档的唯一可能方法是使用第三方应用程序或通过 PDF 打印机和您最喜欢的浏览器创建 PDF。只要 W3C 的建议不严格或者浏览器供应商实现了他们想要的任何方式,其他任何方式都必然会失败。

See also:

也可以看看:

Additional notes

补充说明

If you have a bunch of position:absoluteelements which need to be printed it's sometimes a good question whether an element actually needs to be positioned absolute, or if the same effect can be achieved in a slightly different or easier way. Also note that you should use display:noneon each element that isn't truly needed for the printed media, such as ads, navigations, etc...

如果您有一堆position:absolute需要打印的元素,那么有时一个很好的问题是元素是否确实需要绝对定位,或者是否可以通过稍微不同或更简单的方式实现相同的效果。另请注意,您应该display:none在印刷媒体并非真正需要的每个元素上使用,例如广告、导航等...

回答by Simon Sapin

As you say, web browsers tend to do crazy things when printing. Print-oriented engines are often better.

正如您所说,网络浏览器在打印时往往会做一些疯狂的事情。面向打印的引擎通常更好。

WeasyPrintis an open-sourceengine that renders to PDF and supports absolute positioning as well as CSS 3 Paged Mediato set the page margins:

WeasyPrint是一个开源引擎,可以渲染为 PDF 并支持绝对定位以及CSS 3 Paged Media来设置页边距:

@page { margin: 1cm /* or 0, if you want */ }

回答by Algae

I have tested browser status for printing "position:absolute" elements with the following results:

我已经测试了用于打印“位置:绝对”元素的浏览器状态,结果如下:

  • IE 11: Fail. Doesn't matter what OS, 7,8,8.1.
  • IE 10: Pass. However, you cannot revert to 10 on 8.1 so folks with that are stuck.
  • Firefox up to 38.05 = Fail. Unknown if any version ever worked.
  • IE 11:失败。不管什么操作系统,7、8、8.1。
  • IE 10:通过。但是,您无法在 8.1 上恢复为 10,因此使用它的人会被卡住。
  • Firefox 高达 38.05 = 失败。不知道是否有任何版本有效。

The good news is that it looks like the Blink/WebKit people did their homework instead of using poor code.

好消息是,看起来 Blink/WebKit 的人完成了他们的功课,而不是使用糟糕的代码。

  • Chrome: Pass
  • Opera: Pass
  • 铬:通过
  • 歌剧:通行证

回答by Algae

Make your container to have relative position. That's the only way to keep absolute positioned elements in the same place at every screen and paper. so if your main div (the div where all of your content is located) add following to your css:

使您的容器具有相对位置。这是在每个屏幕和纸张上将绝对定位元素保持在同一位置的唯一方法。因此,如果您的主 div(所有内容所在的 div)将以下内容添加到您的 css 中:

#maindivname{position:relative;}

Should do the trick.

应该做的伎俩。

回答by Dawson

Media Queries will do the trick -- check this link and previous question out, maybe it will help. Suggestions for debugging print stylesheets?

媒体查询可以解决问题——检查这个链接和上一个问题,也许它会有所帮助。 调试打印样式表的建议?

Media Query transitioning px into inches/cm/whatever needed for printing requirements.

媒体查询将像素转换为英寸/厘米/打印要求所需的任何内容。

That border/margin you mentioned is probably your printer's printable area (the grip edge). Most printers need some type of edge to grab and feed the stock. That's why when one prints a full-bleed document (ink to the very edge), it's printed on stock larger than needed, then trimmed down.

您提到的边框/边距可能是您打印机的可打印区域(手柄边缘)。大多数打印机需要某种类型的边缘来抓取和送入库存。这就是为什么当人们打印全出血文档(墨水到最边缘)时,它会打印在比需要大的库存上,然后进行裁切。

回答by JDGuide

set the margin with page setup is the first and primary solutions for printing the HTMLpage or a DIV.

使用页面设置设置边距是打印HTML页面或DIV.

After all not expected result will come then you need some digs on your HTMLpage.

毕竟不会出现预期的结果,那么您需要在HTML页面上进行一些挖掘。

Make a window without title bar or any custom bar using java script.And put all Original data into that window with a position:relativeand also set the media type as print.

使用java脚本制作一个没有标题栏或任何自定义栏的窗口。并将所有原始数据放入该窗口中,position:relative并将媒体类型设置为打印。

position:relative;
media:print;

Hope it will helpful.

希望它会有所帮助。