惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
C
Check Point Blog
B
Blog RSS Feed
G
Google Developers Blog
H
Help Net Security
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Recent Announcements
Recent Announcements
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
DataBreaches.Net
小众软件
小众软件
T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
T
Tailwind CSS Blog
J
Java Code Geeks
MyScale Blog
MyScale Blog
雷峰网
雷峰网
有赞技术团队
有赞技术团队
博客园 - 聂微东

达拉斯・卢

一些没有意义的事情 博客程序的一次大重构 OpenWRT 使用 udp2raw 对抗 WireGuard 阻断 OpenWRT 使用 udp2raw 对抗 WireGuard 阻断 博客程序架构的思考与展望 如何证明你是原创作者 如何证明你是原创作者 Nginx 泛域名配置的隐患与对策 Nginx 泛域名配置的隐患与对策 WISeID S/MIME 证书 WISeID S/MIME 证书 V2EX 刑满释放记 V2EX 刑满释放记 使用 Radicale 在 Ubuntu 24.04 中搭建 vCards CardDav 服务 使用 Radicale 在 Ubuntu 24.04 中搭建 vCards CardDav 服务 邮件服务的域名成功从 SURBL 黑名单移除 邮件服务的域名成功从 SURBL 黑名单移除 网站多语言的设计细节 网站多语言的设计细节 网站评论系统的目前进展和展望 网站评论系统的目前进展和展望 在公网使用 iptables 转发端口时保留客户端 IP 在公网使用 iptables 转发端口时保留客户端 IP 邮件投递平台 Postal 的使用经验 邮件投递平台 Postal 的使用经验 自建 Postal 完美替代 SendGrid 自建 Postal 完美替代 SendGrid 互联网在崩塌吗,然后呢 互联网在崩塌吗,然后呢 在 SvelteKit 应用中使用 JSON-LD
网页的打印样式应该怎么写
达拉斯・卢 · 2024-04-26 · via 达拉斯・卢

刚开始开发本站的程序时,我就考虑到页面打印的问题。Markdown 转 PDF 有很多种方案,而网页转 PDF 体验就很差了,很多不重要的内容影响了打印效果。无论是打印到纸张还是打印到 PDF,网页本身的排版功能是完全胜任的。

后来拜读了宝硕博客的文章《如何创建一个打印友好型的网页》,他结合示例,列出了一些非常重要的建议和方法。本文尝试对其进行总结和补充。

为方便设置打印样式,应当对样式表整体结构进行规划:

/** Base */
:root{
    /* vars */
}
/* and other base styles */

/** Normal */
@media screen {
    /*  */
}

/** print */
@media print {

}

把基础样式外的其他定义放在 @media screen 中,这样做的好处是,在 @media print 中不必再做多余的 reset 和写 !important。如果你使用 sass,写起来更加方便:

article{
    --article-bg-color: #fafafa;
    background-color: var(--article-bg-color);
    font-size: 16px;

    @media screen{
        border: 1px solid #aaa;
    }

    @media print {
        --article-bg-color: #fff;
        print-color-adjust: exact; /* force bg color if need */
        font-size: 12pt;
    }
}

隐藏非正文内容

比如页面布局中的 header 和 footer,侧边栏,操作按钮等等。可以指定规则来隐藏,或者为其添加工具 class:

.print-only{
    display: none;
}
@media print{
    .no-print{
        display: none;
    }
    .print-only{
        display: block;
    }
}

超链接

超链接一般有默认颜色,但在黑白打印中,颜色并不明显,所以最好给出下划线样式。而且应当直接显示出实际的链接:

@media print {
  a:not([href^='#'])::after {
    content: ' (' attr(href) ')';
    font-size: 80%;
  }
}

同理,还可为 abbr 指定显示其 title 属性。

@media print{
    abbr[title]:after {
    content: ' (' attr(title) ')';
    }
}

其他媒体内容

比如视频、音频,可以单独添加脚注信息,并提供二维码。使用 .print-only.no-print 的规则来灵活控制打印的内容。

<video class="no-print"></video>
<img class="print-only"/>

还可以扩展超链接的样式为:

@media print{
    a[data-print-content]::after {
        content: " (" attr(data-print-content) ")";
        font-size: 80%;
        color: #666;
    }
    a:not([href^="#"]):not([data-print-content-none]):not([data-print-content])::after {
        content: "(" attr(href) ")";
        font-size: 80%;
        color: #666;
    }
}
<video data-print-content=""><video>
<a href="https://google.com" data-print-content-none>https://google.com<a>

分页

网页打印时也可像文字排版软件一样插入「分页符」,来避免奇怪的分页行为,影响阅读体验。一般来说,大纲标题最好不要与其后面的内容分割在两页中,一些特殊元素比如代码块最好不要被分割在两页中。同时允许我们在页面中的合适的分页位置手动插入元素。

@media print {
    h2,
    h3,
    h4,
    h5,
    h6 {
        page-break-after: avoid;
    }

    .page-break {
        page-break-after: always;
        break-after: page;
    }

    pre,
    blockquote {
        page-break-inside: avoid;
        box-decoration-break: clone;
    }

    p {
        widows: 4;
        orphans: 3;
    }
}

写文章时,我们可在页面中加入一个分页元素:

<div class="page-break" />

结语

可以执行打印预览,看一下本页面的打印效果。或者使用开发者工具,切换激活 @media print。这两者是有区别的,浏览器的打印预览大多有一些强制的内部规则,比如忽视背景颜色等。也许,我们并不需要 Markdown 转 PDF 的工具。