css - 打印中断引导布局
问题描述
我有以下页面:
<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p>Column 1,1 in small row 1 in xs</p>
</div>
<div class="col-xs-12 col-sm-6">
<p>Column 1,2 in small row 2 in xs</p>
</div>
<div class="col-xs-12 col-sm-6">
<p>Column 2,1 in small row 3 in xs</p>
</div>
<div class="col-xs-12 col-sm-6">
<p>Column 2,2 in small row 4 in xs</p>
</div>
</div>
</div>
</body>
</html>
此页面在查看时按预期显示(即在小屏幕上有 2 列和 2 行,在移动设备上有 4 行)但是问题是在尝试打印时。
当我在 Chrome 中执行 CTRL+P 时,我得到以下预览:
页面大小设置为 A4。该问题在 Firefox 中不会出现(但在 IE 和 Edge 中也会出现)
知道如何让打印视图呈现小(或中等)布局而不是移动视图吗?
解决方案
演示
(我觉得我已经实施的修复有点太多了,但我认为没有其他方法可以解决这个问题)
(如果您想知道为什么我托管了一个网站,而不是我在评论中解释过的 SO 片段或 jsfiddle 之类的东西)
解释
为什么我在打印中获得“移动”视图?
width of A4 = 210mm ≈ 8.27 in ≈ 595 px (72 dpi)
xs
适用于width < 768px
- 所以从技术上讲,chrome 的做法是正确的,而其他浏览器的做法是不正确的
如何解决这个问题?
- Bootstrap 以移动优先模式编写。
- 这意味着样式表看起来像这样:
.col-xs-12 {
width: 100%;
}
@media (min-width: 768px){
.col-sm-6 {
width: 50%;
}
}
- 现在,如果我
@media (min-width: 768px)
仅在打印期间打开规则,我的问题将得到解决。 - 为了实现这一点,我们将
@media (min-width: 768px)
使用其中的所有规则document.styleSheets
(不要忘记添加crossorigin="anonymous"
引导程序<link>
,否则在访问样式表时会出错) - 一旦我们有了所有这些样式,我们会将它们包装在 a中
<style>
并附加到事件中<head>
beforeprint
- 在
afterprint
活动中,我们将删除它<style>
代码(与演示相同):
window.addEventListener("beforeprint", function(){
let printStyleSheet = document.createElement("style");
printStyleSheet.classList.add("print-stylesheet");
document.head.appendChild(printStyleSheet)
let printRulesText = "";
Array.from(document.styleSheets).forEach(styleSheet => {
Array.from(styleSheet.cssRules)
.filter(rule => rule.media && /(min-width: 768px)/g.test(rule.media.mediaText))
.forEach(rule => {
Array.from(rule.cssRules).forEach(rule => printRulesText += rule.cssText)
})
})
printStyleSheet.innerHTML = printRulesText;
})
window.addEventListener("afterprint", function(){
Array.from(document.querySelectorAll(".print-stylesheet")).forEach(style => style.remove())
})
注意:如果您想要中型桌面视图 (md),这将为您提供平板电脑视图 (sm),您必须同时打开这两个视图,对于大型桌面 (lg) 也同样min-width: 768px
如此min-width: 992px
这行得通吗?
- 它适用于问题中的代码
- 它也应该适用于其他组件。
我可以通过html, body { width: 769px }
在打印期间应用来修复它吗?(如 769 > 768)
- 不,它不起作用,因为媒体查询适用于
viewport
html 或正文的宽度而不是宽度
好的,我可以在打印期间附加<meta name="viewport" content="width=769">
和删除其他视口元数据吗?(如 769 > 768)
- 嗯...不。它不起作用。(我认为它应该但不知何故不起作用)
还有其他修复吗?
xs
像@Arex 那样手动覆盖样式获取引导 css 源代码并使用
print
媒体查询对其进行修改,如下所示:.col-xs-12 { width: 100%; } @media (min-width: 768px){ .col-sm-6 { width: 50%; } } /* add such rules everywhere */ @media print{ .col-sm-6 { width: 50%; } }
将当前页面的所有内容放在一个
iframe
with中,width: 100%; height: 100%; border: none;
并制作其他所有内容display: none;
。但我觉得它不起作用,因为如果iframe
获取滚动条,视图中的内容将不会被打印。看起来也更hackish
PS:这很明显,但让我明确地说出来......实施的修复(如演示中所见)不仅修复了网格系统或问题中的片段......但修复了所有组件的行为(按钮,表,输入,网格等)通过伪造min-width: 768px
媒体查询。这就是OP想要的。不单独固定组件
PPS:阅读 Floyd 的评论,我们可以在构建时创建打印样式表,这更好
推荐阅读
- nginx - Nginx 基本身份验证不适用于某些网址
- angular - 如何知道发出的事件已被订阅并且已采取或未采取行动?(角6)
- javascript - 使用带有开始月份和结束月份的时刻获取一系列月份
- php - 在哪里放置作为参数提示的类的类声明?
- javascript - TextArea 下拉菜单 - 不下推页面内容
- angular - 角材料对话框
- ios - swinject 是否重新实例化对象?
- android - 如何从 childfragment 到 parentfragment 获得价值?
- typo3 - TYPO3 v9.5.0 - 错误消息:请求的页面不存在 /robots.txt
- python - 如何在 Google Colab 终端命令中使用 Python 变量?