165

I'm using Twitter-Bootstrap and I need to be able to print the page the way it looks on the browser. I'm able to print other pages made with Twitter-Bootstrap just fine but I can't seem to print my page that uses purely Twitter-Bootstrap. Am I missing a tag somewhere?

Official TB page when printed: Twitter Bootstrap Page

My page when printed: enter image description here

What my page actually looks like: enter image description here

Jay Q.
  • 4,979
  • 3
  • 33
  • 36

9 Answers9

182

Bootstrap 3.2 update: (current release)

Current stable Bootstrap version is 3.2.0.
With version 3.2 visible-print deprecated, so you should use like this:

Class                        Browser    Print
 -------------------------------------------------
.visible-print-block         Hidden        Visible (as block)
.visible-print-inline        Hidden        Visible (as inline)
.visible-print-inline-block  Hidden        Visible (as inline-block)
.hidden-print                Visible       Hidden

Bootstrap 3 update:

Print classes are now in documents: http://getbootstrap.com/css/#responsive-utilities-print

Similar to the regular responsive classes,
       use these for toggling content for print.

Class            Browser    Print
 ----------------------------------------
.visible-print   Hidden     Visible
.hidden-print    Visible    Hidden

Bootstrap 2.3.1 version:

After adding bootstrap.css file into your HTML,
Find the parts that you don't want to print and add hidden-print class into tags. Because css file includes this:

@media print {
  .visible-print  { display: inherit !important; }
  .hidden-print   { display: none !important; }
}
trante
  • 33,518
  • 47
  • 192
  • 272
  • 4
    Isn't there a class to make something visible on both the browser and printer in the case where I make everything (`body`) invisible with `.hidden-print`, but want to override a specific element to be shown? – Vincent Poirier Mar 25 '15 at 20:36
  • 1
    @VincentPoirier - if an element is hidden, everything inside it is hidden. So it is not meaningful to hide body, but unhide something that is part of body. Because there would be no context (container) in which to show that sub-element. Instead do css to hide all your leaf elements (e.g. put a default class on your inner divs), then use appropriate css class or id where desired to be visible. Will likely require some experimentation to get this exactly right. – ToolmakerSteve Aug 03 '15 at 18:58
158

Be sure to have a stylesheet assigned for printing.
It could be a separate stylesheet:

<link rel="stylesheet" type="text/css" media="print" href="print.css">

or one you share for all devices:

<link rel="stylesheet" type="text/css" href="bootstrap.min.css"> # Note there's no media attribute

Then, you can write your styles for printers in the separate stylesheets or in the shared one using media queries:

@media print {
    /* Your styles here */
}
albertedevigo
  • 18,262
  • 6
  • 52
  • 58
  • 31
    I just added this: and didn't need to do anything else. Worked like a charm. Thanks! – Jay Q. Sep 06 '12 at 15:41
  • 13
    If you're already using this stylesheet, chances are you have you currently have `media="screen"`, which will not be seen by a printer. You can either switch this to `media="all"`, or simply remove `media` as the above answer suggests. – Wex Nov 04 '13 at 23:57
  • albertedevigo, I need some help regarding the styling. Like change font-size, widths, ... what exactly needed to be changed? TIA. @JayQ. : Is that still working or outdated? cause I can't get it to work. – musafar006 Apr 29 '16 at 17:07
  • @dreamster, just include your styles in the stylesheet that applies to printing. Note that CSS cascading still works; so order, inheritance and selector priorities will influence the outcome. You'd probably ask a new question with your own code. – albertedevigo May 02 '16 at 06:31
114

Replace every col-md- with col-xs-

eg: replace every col-md-6 to col-xs-6.

This is the thing that worked for me to get me rid of this problem you can see what you have to replace.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
Sonam
  • 2,322
  • 2
  • 13
  • 5
  • Thanks ! Was having problem with the scale of the HTML view compared to the Print View... everything is good now ! – David Bélanger Jan 20 '15 at 20:42
  • 2
    Hey thanks! I was facing problem when printing my page, each `div` used to go below the previous one. This answer gave me a hint, I added `col-xs-*` before each `col-md-*` and this fixed the issue. DISCLAIMER: I didn't test adding a container as `
    ` which may also have solved the problem(seems obvious).
    – Fr0zenFyr May 29 '15 at 10:05
  • 6
    Unless one intended to have a different layout for narrow screens (e.g. phone) than for printing. Seems odd that bootstrap printer logic thinks its print screen is so narrow. – ToolmakerSteve Aug 03 '15 at 19:02
  • 3
    This should be on the top. – Suraj Aug 04 '15 at 05:58
  • Just to add that you can replace col-md- as the answer says or you can just add col-xs- like: class="col-md-6 col-xs-6" and you can mix and match depending on the requirements of your design. – zaidorx Mar 17 '17 at 18:29
  • Thanks. This helped me in a similar issue as well. – PDoria Mar 22 '18 at 15:39
  • only problem is now your layout might not be as responsive because you have taken what used to break at around 768px (I think) and made it full width all the way through. I think the chosen answer is the best as it decouples the purposes of digital and print styles and allows you to have the best of both worlds: responsive digital and good looking print – ardev May 21 '18 at 19:48
17

There's a section of @media print code in the css file (Bootstrap 3.3.1 [UPDATE:] to 3.3.5), this strips virtually all the styling, so you get fairly bland print-outs even when it is working.

For now I've had to resort to stripping out the @media print section from bootstrap.css - which I'm really not happy about but my users want direct screen-grabs so this'll have to do for now. If anyone knows how to suppress it without changes to the bootstrap files I'd be very interested.

Here's the 'offending' code block, starts at line #192:

@media print {
  *,
  *:before,enter code here
  *:after {
    color: #000 !important;
    text-shadow: none !important;
    background: transparent !important;
    -webkit-box-shadow: none !important;
            box-shadow: none !important;
  }
  a,
  a:visited {
    text-decoration: underline;
  }
  a[href]:after {
    content: " (" attr(href) ")";
  }
  abbr[title]:after {
    content: " (" attr(title) ")";
  }
  a[href^="#"]:after,
  a[href^="javascript:"]:after {
    content: "";
  }
  pre,
  blockquote {
    border: 1px solid #999;

    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr,
  img {
    page-break-inside: avoid;
  }
  img {
    max-width: 100% !important;
  }
  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }
  h2,
  h3 {
    page-break-after: avoid;
  }
  select {
    background: #fff !important;
  }
  .navbar {
    display: none;
  }
  .btn > .caret,
  .dropup > .btn > .caret {
    border-top-color: #000 !important;
  }
  .label {
    border: 1px solid #000;
  }
  .table {
    border-collapse: collapse !important;
  }
  .table td,
  .table th {
    background-color: #fff !important;
  }
  .table-bordered th,
  .table-bordered td {
    border: 1px solid #ddd !important;
  }
}
Hugo Yates
  • 2,081
  • 2
  • 26
  • 24
6

Best option I found was http://html2canvas.hertzen.com/
http://jsfiddle.net/nurbsurf/1235emen/

html2canvas(document.body, {  
  onrendered: function(canvas) {
    $("#page").hide();
    document.body.appendChild(canvas);
    window.print();
    $('canvas').remove();
    $("#page").show();
  }
});
Bodie Leonard
  • 123
  • 1
  • 7
  • I tried both 0.4 and 0.5 but neither of them worked. 0.5 appended some good looking stuff after my page, but the original page was still there, and then how I supposed to print that? Trying 0.4 triggered a print, the original page was also still there, and the render was kinda broken. – Csaba Toth Jun 29 '15 at 20:20
3

In case someone is looking for a solution for Bootstrap v2.X.X here. I am leaving the solution I was using. This is not fully tested on all browsers however it could be a good start.

1) make sure the media attribute of bootstrap-responsive.css is screen.

<link href="/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen" />

2) create a print.css and make sure its media attribute print

<link href="/css/print.css" rel="stylesheet" media="print" />

3) inside print.css, add the "width" of your website in html & body

html, 
body {
    width: 1200px !important;
}

4.) reproduce the necessary media query classes in print.css because they were inside bootstrap-responsive.css and we have disabled it when printing.

.hidden{display:none;visibility:hidden}
.visible-phone{display:none!important}
.visible-tablet{display:none!important}
.hidden-desktop{display:none!important}
.visible-desktop{display:inherit!important}

Here is full version of print.css:

html, 
body {
    width: 1200px !important;
}

.hidden{display:none;visibility:hidden}
.visible-phone{display:none!important}
.visible-tablet{display:none!important}
.hidden-desktop{display:none!important}
.visible-desktop{display:inherit!important}
Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
abchau
  • 61
  • 1
  • 4
2

2 things FYI -

  1. For now, they've added a few toggle classes. See what's available in the latest stable release - print toggles in responsive-utilities.less
  2. New and improved solution coming in Bootstrap 3.0 - they're adding a separate print.less file. See separate print.less
0

To make print view look like tablet or desktop include bootstrap as .less, not as .css and then you can overwrite bootstrap responsive classes in the end of bootstrap_variables file for example like this:

@container-sm:      1200px;
@container-md:      1200px;
@container-lg:      1200px;
@screen-sm:         0;

Don't worry about putting this variables in the end of the file. LESS supports lazy loading of variables so they will be applied.

Hrvoje Golcic
  • 3,446
  • 1
  • 29
  • 33
0

If you want to keep columns on A4 print (which is around 540px) this is a good idea

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

.make-print-A4-column(@columns) {
    @media print {
        float: left;
        width: percentage((@columns / @grid-columns));
    }
}

You can use it like this:

<div class="col-sm-4 col-print-A4-4">

User366
  • 765
  • 4
  • 9