winar_阿进

被人遗忘了的打印样式表

winar_阿进 · 2016-12-27翻译 · 172阅读 原文链接

Aaron Gustafson指出当他在打印某一个页面的时候,原本有序的界面也变得杂乱不堪,也因此向Indiegogo发送了一篇微博

当我看到这个消息的时候真的感到震惊,我忽然意识到已经有很长的时间没有优化一个页面的打印样式了,甚至都没有在页面的检查上花过心思。

这样真的很不好,也许是因为我们一直关注在浏览器上,我们希望我们的网站能够在各种类型各种分辨率的浏览器中都能完美的呈现给用户,也或许是因为我平常很少打印页面的缘故吧,不管怎样,print style sheets真的不应该被遗忘的。

为了能够在各种环境下,我们的网站都能够无障碍的使用,对页面的打印效果进行优化就显得很有必要。我们不能够无故猜想用户的行为。总有用户会打印页面的。我们应该考虑的是我们所编写的文章、博客推送、食谱、联系人信息、说明书或者是房地产网站,总会有某些人在需要的时候进行页面的打印。

很早以前我就放弃了在家里使用打印机的人,因为他们几乎在使用打印机十分钟后就放弃了。但是,并不是每一个人都和我一样... -Heydon Pickering (Inclusive Design Patterns)

自我反省下,如果你也和我处在相同的境地,那么这篇文章将会对你非常有用。

如果你还没有尝试过用CSS美化你的打印页面样式,那么我们就一起开始吧。

1. 嵌入打印样式表

嵌入打印样式最好的方式就是在你的CSS样式中声明 @media 规则。

body {
    font-size: 18px;
}
@media print {
    /* 添加打印规则 */
    body {
        font-size: 28px;
    }
}

同样你也可以在HTML文件中嵌入打印样式文件,但是这样会额外多出一个的请求。

`<link media="print" href="print.css" />`

2. 测试

你不需要每调一次代码就打印一页。用浏览器就可以将你的页面导出为PDF文件,该文件会展示打印预览,甚至你可以直接在浏览器中调试。

  • 在Firefox中调试打印样式的方法如下:打开开发者工具Shift + F2工具 > Web Developer > Developer Toolbar);在浏览器窗口底部的输入框输入media emulate print然后单击enter;当前激活的标签页将会以print媒体类型来显示,直到你关闭或者刷新该标签页。

Firefox的打印样式模拟

  • 在Chrome中:打开开发者工具(CMD + Opt + I (macOS) 或 Ctrl + Shift + I (Windows)或视图>开发者>开发者工具);打开console标签(Esc);打开渲染面板(rendering pane),开启Emulate CSS Media and select Print选项。 Chrome的打印样式模拟

3. 绝对单位

绝对单位对屏幕来说是很不友好的,但是对于印刷来说则相反。在打印样式中,使用像cm, mm, in, pt or pc这样的绝对单位是很安全的,并且也推荐这么使用。

section {
    margin-bottom: 2cm;
}

4. 页面具体规则

可以使用@page规则具体的定义页面的尺寸,方向以及页边距属性,如果想要所有的页面都有一个边距,使用这个规则会非常方便。

@media print {
     @page {
        margin: 1cm;
    }
}

@page规则是页面媒体模块的一部分。包括了很多有用的东西,比如说:选择打印的第一页,或空白页,在页面的一角定位元素,还有其他一些功能。。甚至可以用该属性出版书籍

5. 控制页面断页

因为打印的页面是不像网站那样可以无穷尽的向下面拉的。内容在一个页面上肯定会断开,到第二个页面。如果断页这种情乱出现了,我们可以用5个属性控制它。

在一个元素前使页面断页

如果我们想要一个元素总是在页面的开头,我们可以强制页面设置page-break-before属性来进行断页。

section {
    page-break-before: always;
}

page-break-before on MDN

在一个元素之后断页

page-break-after属性可以让我们强制或者避免页面在一个元素之后断页。

h2 {
    page-break-after: always;
}

page-break-after on MDN

在一个元素内部进行断页

如果你想避免页面的一个元素被分在了两张纸上,就采用page-break-inside属性吧。

ul {
    page-break-inside: avoid;
}

page-break-inside on MDN

Widows and Orphans

有时候你不想强制页面断开,至少你可以控制在压面上显示多少行或者在下一页显示多少行。比如说:如果一个段落的最后一行在当前页显示不下,那么该段落的倒数两行都会显示在下一页。因为widows属性控制这个特性,默认值是2,我们也可以改变这个值。

p {
    widows: 4;
}

如果页面只能容纳下一行,还有另一种解决办法,整段都打印在下一页,orphans属性代表这种方法,该属性的默认值也是2

p {
    orphans: 3;
}

上面的代码表示,该页面至少能够容纳下三行,否则的话就将该段打印在下一页。

这里有一些例子。(也可以查看调试版本进行测试)。

并不是所有的属性都能适配所有的浏览器,你应该在不同的浏览器下测试你的打印样式。

6. 重新设置你的页面样式

为了打印效果,改变页面的样式(像background-color, box-shadowcolor)也是可以的。

可以参考一下HTML5样板打印样式表:

*,
*:before,
*:after,
*:first-letter,
p:first-line,
div:first-line,
blockquote:first-line,
li:first-line {
    background: transparent !important;
    color: #000 !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

打印样式表是可以使用!important属性的少数之一。

7. 删掉不必要的内容

为避免你不必要的内容浪费墨水,你可以删除掉展示性内容,广告,导航,等,将他们设置为display: none。 你也可以只显示主要的内容,而将其他的内容隐藏掉。

body > *:not(main) {
    display: none;
}

8. 将链接中的网址显示出来

在不知道网址的情况下将一个链接打印出来是一点用处也没有的。

我们可以很容易的把一个网址显示在他的文字旁边。

a[href]:after {
    content: " (" attr(href) ")";
}

以下属性设置会显示出网站的相对链接,绝对链接,锚点等,这样可以大大增加打印出来的实用性。

a[href^="http"]:not([href*="mywebsite.com"]):after {
    content: " (" attr(href) ")";
}

我知道这看起来很疯狂。这一行表示:在每一个具有href属性的链接旁展示href属性的值。他以http开头,但可能他的值不像mywebsite.com这样。

9. 将缩写的内容展开

缩写应该被包含在元素里面,他的缩写包含在title属性中,将元素的缩写展示在打印页中也是很有用的。

abbr[title]:after {
    content: " (" attr(title) ")";
}

10. 强制打印页面背景

通常,如果默认设置的话,浏览器不会打印背景颜色和背景图片,但有时你可能想要强制打印出来背景。不标准的属性print-color-adjust会允许你重写浏览器的默认设置。

header {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

11. 媒体查询

如果你像下面这样写了媒体查询的设置,请注意,这些设置并不会应用在打印样式中。

@media screen and (min-width: 48em) {
    /* screen only */ 
}

为什么呢?因为这些规则仅仅使用在以下这些情况:min-width48em,并且media-typescreen。删除掉screen关键字之后,媒体查询仅仅被min-width所限制。

@media (min-width: 48em) {
    /* all media types */ 
}

12. 打印地图

当前版本的火狐浏览器和Chrome浏览器支持打印地图,但是还有一些浏览器不支持,像Safari。一些服务商提供静态地图服务,也可以用这样的服务来进行地图的打印。

.map {
    width: 400px;
    height: 300px;
    background-image: url('http://maps.googleapis.com/maps/api/staticmap?center=Wien+Floridsdorf&zoom=13&scale=false&size=400x300&maptype=roadmap&format=png&visual_refresh=true');
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

13. 二维码

一篇杂志上的文章写了一些很不错的建议。其中的一条就是在你的打印页放一个二维码,这样你的用户就可以不用输入整个网址就可以获得最新的版本了。

Bonus: 打印非优化页面

在我调查的过程中,我发现了对于打印非优化页面非常有用的工具,有了Printliminator,你可以很简单的通过点击元素来删除他们。 这是他的一个样例和在Github的库。

Bonus II: Gutenberg

如果你愿意使用框架,你也许会喜欢Gutenberg,他会帮助你优化你的打印页面。

Bonus III: Hartija

还有一个由Vladimir Carrer出的打印样式框架,叫做Hartija


就是这样了,如果你想要看这些属性在实际中应用的例子,可以看我在CodePen上做的一个调试版本)。

希望你会喜欢这篇文章。

PS:感谢Eva帮助我校对了文稿以及Mario的建议。

参考资源

译者winar_阿进尚未开通打赏功能