打印中断引导程序布局

apo*_*fos 1 css printing google-chrome twitter-bootstrap-3

我有以下页面:

<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>
Run Code Online (Sandbox Code Playgroud)

在查看时,此页面按预期显示(即,在小屏幕上有2列和2行,在移动设备上有2行),但是问题出在尝试打印时。

当我在Chrome中执行CTRL + P时,会得到以下预览:

在此处输入图片说明

页面大小设置为A4。在Firefox中不会发生此问题(但在IE和Edge中也会发生)

任何想法如何获取打印视图以呈现小(或中)布局而不是移动视图?

Dev*_*h J 5

演示版

https://so51099397.surge.sh/

(我觉得我已实施的解决方案有点过多,但我认为没有其他方法可以解决此问题)

(如果您想知道为什么我托管一个网站,而不是我在评论中解释过的SO片段或jsfiddle之类的网站)

说明

为什么我可以打印“移动”视图?

  1. width of A4 = 210mm ? 8.27 in ? 595 px (72 dpi)
  2. xs 适用于 width < 768px
  3. 因此从技术上讲,chrome在做什么是正确的,而其他浏览器在做什么是不正确的

如何解决这个问题?

  1. Bootstrap以移动优先模式编写。
  2. 意味着样式表看起来像这样:
    .col-xs-12 {
        width: 100%;
    }
    @media (min-width: 768px){
        .col-sm-6 {
            width: 50%;
        }
    }
Run Code Online (Sandbox Code Playgroud)
  1. 现在,以某种方式,如果我@media (min-width: 768px)仅在打印过程中拆开规则,那么我的问题将得到解决。
  2. 为了实现这一点,我们将@media (min-width: 768px)使用所有内部规则document.styleSheets(不要忘记添加crossorigin="anonymous"引导程序<link>,否则在访问样式表时会出现错误)
  3. 一旦拥有所有这些样式,我们会将它们包装在中,<style>然后附加到<head>on beforeprint事件中
  4. 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())
})
Run Code Online (Sandbox Code Playgroud)

注意:这会给你的平板视图(SM),如果你想在媒体桌面视图(MD),你必须解开两个,min-width: 768px以及min-width: 992px类似的大型桌面(LG)也

这样行吗?

  1. 它适用于问题中的代码
  2. 它也应该适用于其他组件。

我可以html, body { width: 769px }在打印过程中通过应用程序解决它吗?(如769> 768)

  1. 不,这是行不通的,因为媒体查询有效,viewport而不是HTML或正文的宽度

好的,这样我可以<meta name="viewport" content="width=769">在打印过程中追加和删除其他视口元吗?(如769> 768)

  1. 嗯...不行。(我认为应该,但是不起作用)

还有其他解决方法吗?

  1. 手动覆盖xs@Arex这样的样式
  2. 获取bootstrap 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%;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将当前页面的所有内容放在iframewith中,width: 100%; height: 100%; border: none;然后进行其他操作display: none;。但是我感觉这是行不通的,因为如果iframe获取滚动条,则视图中的内容将不会被打印。看起来也更黑

PS:很明显,但是让我明确地说一下...实现的修复(如演示中所示)不仅解决了网格系统或问题中的代码段,而且修复了所有组件的行为(按钮,表格,输入,网格等),方法是伪造min-width: 768px媒体查询。这就是OP想要的。没有单独固定组件

  • @Islam 我故意使用了外部托管站点,因为如果我使用 SO 代码段或 jsfiddle,将打印出“iframe”而不是实际内容。尝试打印问题中的片段,您将获得 2x2 列而不是屏幕截图中的 1x4。也可以使用类似 stackblitz 的东西,但代码又不一样了。他们也放了一些其他的东西。如果我想要确切的代码,我必须托管一个网站。:) (2认同)