79

If you take this example (view it here: http://www.bootply.com/93816)

<div class="container">
  <div class="row">
    <div class="col-md-6">Column1</div>
    <div class="col-md-6">Column2</div>
  </div>
</div>

When you do a print preview of the generated page, it seems to cause the columns to stack/break (as if the float is removed) instead of displaying them in the usual grid layout.

I've had a look at the @media print sections of bootstrap.css and I can't see anything related to div that would cause that to happen.

Does anyone know how to avoid this?

AndyC
  • 2,513
  • 3
  • 17
  • 17
  • 7
    IIRC this is caused by the page only being a few hundred "pixels" across (~500px), meaning the other media queries normally meant for phones/tablets apply to page print as well – Bojangles Nov 13 '13 at 08:25
  • 2
    A good solution: http://stackoverflow.com/a/20244712/717267 – Eduardo Cuomo Sep 24 '14 at 20:45

4 Answers4

128

Bojangles comment got me in the right direction, so I'll answer my own question.

Using the 'xs' size grid columns, which according to http://getbootstrap.com/css/#grid-options is for "Extra small devices Phones (<768px)", Bootstrap happily prints as expected.

<div class="container">
  <div class="row">
    <div class="col-xs-6">Column1</div>
    <div class="col-xs-6">Column2</div>
  </div>
</div>
AndyC
  • 2,513
  • 3
  • 17
  • 17
  • 2
    Can fix it, but hope there is correct way to do it. using xs size, being picky, will make it hard to read on smaller phone... iPhone included. – Nestor Mar 20 '14 at 06:35
  • 6
    i tried this and it didn't work. Using bootstrap 3.1 – Alexis May 08 '14 at 10:01
  • 2
    Thanks **Try 1** : I used col-xs it worked **Try 2** : col-sm + print in Landscape mode Also worked **Try 3** : col-md + print in Landscape mode Also worked **Try 4** col-lg + print in Landscape mode Also worked **Try 5** col-lg print In Portrait mode broke **Try 6** col-md print In Portrait mode broke - - -All this variations might Be due to my uneven div setup – vijay May 05 '15 at 13:47
  • 4
    As @vijay said it will use col-xs in print mode, is there away to change this? i need the page to be printed as it looks on the large devices (col-lg)? – Anas Aug 17 '15 at 10:35
  • Bootstrap 4.x kicked in my face and said you can't cheat me like this. – Jamshaid K. Feb 23 '20 at 03:08
33

The solution has to be on the elements not the page itself. You also shouldn't rely on col-xs-... because these are for small screen/devices.

The issue is that the page itself is small in terms of pixels, so bootstrap thinks it needs to apply the xs styles.

The issue won't be addressed by the Bootstrap team and is related to https://code.google.com/p/chromium/issues/detail?id=273306

The Bootstrap solution was to obscurely document this 'quirky' behavior https://github.com/twbs/bootstrap/issues/12078.

In my opinion, there should be a col-print-... set of layout classes so extra small and print can co-exist.

My interim solution is as follows:

@media print {
  [class*="col-sm-"] {
    float: left;
  }
}

You could use col-print, in our case we're using sm, not xs because we want xs to block the layout, which is why utilizing those classes for print won't work.

Gerard
  • 513
  • 4
  • 7
23

Based on Gerard solution, you can use the bootstrap mixin .make-grid() like this, so the print is doesn't ever fall to the xs size

@media print {
  .make-grid(sm);
}

or the generated css (if you don't like using less):

@media print {
  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
    float: left;
  }
  .col-sm-12 {
    width: 100%;
  }
  .col-sm-11 {
    width: 91.66666667%;
  }
  .col-sm-10 {
    width: 83.33333333%;
  }
  .col-sm-9 {
    width: 75%;
  }
  .col-sm-8 {
    width: 66.66666667%;
  }
  .col-sm-7 {
    width: 58.33333333%;
  }
  .col-sm-6 {
    width: 50%;
  }
  .col-sm-5 {
    width: 41.66666667%;
  }
  .col-sm-4 {
    width: 33.33333333%;
  }
  .col-sm-3 {
    width: 25%;
  }
  .col-sm-2 {
    width: 16.66666667%;
  }
  .col-sm-1 {
    width: 8.33333333%;
  }
  .col-sm-pull-12 {
    right: 100%;
  }
  .col-sm-pull-11 {
    right: 91.66666667%;
  }
  .col-sm-pull-10 {
    right: 83.33333333%;
  }
  .col-sm-pull-9 {
    right: 75%;
  }
  .col-sm-pull-8 {
    right: 66.66666667%;
  }
  .col-sm-pull-7 {
    right: 58.33333333%;
  }
  .col-sm-pull-6 {
    right: 50%;
  }
  .col-sm-pull-5 {
    right: 41.66666667%;
  }
  .col-sm-pull-4 {
    right: 33.33333333%;
  }
  .col-sm-pull-3 {
    right: 25%;
  }
  .col-sm-pull-2 {
    right: 16.66666667%;
  }
  .col-sm-pull-1 {
    right: 8.33333333%;
  }
  .col-sm-pull-0 {
    right: auto;
  }
  .col-sm-push-12 {
    left: 100%;
  }
  .col-sm-push-11 {
    left: 91.66666667%;
  }
  .col-sm-push-10 {
    left: 83.33333333%;
  }
  .col-sm-push-9 {
    left: 75%;
  }
  .col-sm-push-8 {
    left: 66.66666667%;
  }
  .col-sm-push-7 {
    left: 58.33333333%;
  }
  .col-sm-push-6 {
    left: 50%;
  }
  .col-sm-push-5 {
    left: 41.66666667%;
  }
  .col-sm-push-4 {
    left: 33.33333333%;
  }
  .col-sm-push-3 {
    left: 25%;
  }
  .col-sm-push-2 {
    left: 16.66666667%;
  }
  .col-sm-push-1 {
    left: 8.33333333%;
  }
  .col-sm-push-0 {
    left: auto;
  }
  .col-sm-offset-12 {
    margin-left: 100%;
  }
  .col-sm-offset-11 {
    margin-left: 91.66666667%;
  }
  .col-sm-offset-10 {
    margin-left: 83.33333333%;
  }
  .col-sm-offset-9 {
    margin-left: 75%;
  }
  .col-sm-offset-8 {
    margin-left: 66.66666667%;
  }
  .col-sm-offset-7 {
    margin-left: 58.33333333%;
  }
  .col-sm-offset-6 {
    margin-left: 50%;
  }
  .col-sm-offset-5 {
    margin-left: 41.66666667%;
  }
  .col-sm-offset-4 {
    margin-left: 33.33333333%;
  }
  .col-sm-offset-3 {
    margin-left: 25%;
  }
  .col-sm-offset-2 {
    margin-left: 16.66666667%;
  }
  .col-sm-offset-1 {
    margin-left: 8.33333333%;
  }
  .col-sm-offset-0 {
    margin-left: 0%;
  }
}
Paolo Sanchi
  • 783
  • 9
  • 19
  • I'm using Bootstrap version 4.3.1 and using a modified version of this method worked for me: Using @media print, I only applied the percentage attributes to .col-sm-1 through .col-sm-12 because the other classes are not used in Bootstrap 4. Now I just need to find a similar solution for variable-width columns, i.e. when .col-sm-auto and col are used together in a row. I do not want the print view of variable-width columns to default to mobile viewport sizing. – SukieC Nov 06 '19 at 16:46
7

I created a separate print.css and added the following:

@page {
    size: A3;
    margin-left: -5cm;
    margin-right: -5cm;
    }

Works fine with Chrome, but the negative margins kills IE. Firefox doesn't seem to need it. I would be interested in another approach.

  • For me IE11's Shrink To Fit works fine as long as we define a fixed width to the top container and left-align it (remove the auto margin), to not apply this code for IE11 I've used `@media print and (-webkit-min-device-pixel-ratio:0)` to only match chrome, but please note that my internal system had no FF requirement. – Francisco Aquino Jul 01 '15 at 17:25