117

I'm using a CSS property.

If I use page-break-after: always;, it prints an extra blank page before.

If I use page-break-before: always;, it prints an extra blank page after. How can I avoid this?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.print{
    page-break-after: always;

}
</style>
<script type="text/javascript">
window.print();
</script>
</head>
<body>
<div class="print">fd</div>
<div class="print">fdfd</div>
</body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Angelin Nadar
  • 8,944
  • 10
  • 43
  • 53

32 Answers32

120

Try this:

@media print {
    html, body {
        height: 99%;    
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
giannis.epp
  • 1,489
  • 1
  • 11
  • 9
  • 2
    For me worked: @media print { html{ height: 99%; } }, with body the document created was bigger – Gustavo Feb 17 '14 at 09:33
  • 13
    In my case, [Zurb Foundation](http://foundation.zurb.com/) was setting html and body to `height: 100%`. I was able to override this with `height: auto` – zacharydl Oct 18 '14 at 03:03
  • 7
    Confirming that @zacharydl's comment works for me, and also that `height: auto;` is more elegant than `height: 99%;` – jontsai Oct 06 '15 at 15:22
  • I had this issue, because i was setting html height to 101% to force a scrollbar to always show. (Eliminates the jump between pages) - so yes, 100% height in the print style is a tasty fix! - cheers. – rob_james Jun 30 '16 at 13:11
  • @rob_james to avoid using 101%, you can set overflow-y: scroll; to always have the scrollbar visible – user161592 Aug 17 '16 at 15:20
  • 1
    Still working to this day! – Kim Skogsmo Nov 04 '21 at 10:02
  • seems to be fine even with `height: 99.9%;` – curveball Oct 05 '22 at 09:45
91

You could maybe add

.print:last-child {
     page-break-after: auto;
}

so the last print element will not get the extra page break.

Do note that the :last-child selector is not supported in Internet Explorer 8, if you're targetting that wretch of a browser.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AKX
  • 152,115
  • 15
  • 115
  • 172
58

The solution described here helped me (webarchive link).

First of all, you can add a border to all elements to see what causes a new page to be appended (maybe some margins, paddings, etc.).

div { border: 1px solid black;}

And the solution itself was to add the following styles:

html, body { height: auto; }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Michael Radionov
  • 12,859
  • 1
  • 55
  • 72
51

if None of those works, try this

@media print {

    html, body {
      height:100vh; 
      margin: 0 !important; 
      padding: 0 !important;
      overflow: hidden;
    }

}

make sure it is 100vh

Bryan Chan
  • 519
  • 4
  • 2
  • 6
    setting the height to 100vh solved my problem. Thanks – user2398069 Aug 11 '18 at 15:43
  • 3
    "@media print { * { overflow: hidden!important; } }" is very important for me. – shinriyo Dec 12 '18 at 03:42
  • 1
    Finally an answer to an obscure problem! Safari on OSX was showing a completely blank page while Chrome, FF _and_ Edge where all good with the preview. Thanks a lot! – pop Mar 04 '20 at 16:06
  • 3
    Having the height set to 100vh seems to be keeping it from loading any more than one page, so that if the document has more than one page only the first page loads on the preview – Filipe Jul 10 '20 at 18:53
  • thanks bro u save my day :+1: – anztrax Nov 10 '21 at 19:12
9

This works for me

.print+.print {
    page-break-before: always;
}
Lam
  • 429
  • 6
  • 12
  • This worked for me better than the rest! Some more info here: http://blog.jonesed.net/2012/10/how-to-remove-trailing-blank-pages-when-setting-up-printable-html/ – RemarkLima Nov 17 '14 at 18:26
  • The [weird syntax highlighter](https://meta.stackexchange.com/questions/353983/goodbye-prettify-hello-highlight-js-swapping-out-our-syntax-highlighter) doesn't like it. Perhaps turn it off? – Peter Mortensen Aug 18 '23 at 21:06
7

I don't know (as for now) why, but this one helped:

   @media print {
        html, body {
            border: 1px solid white;
            height: 99%;
            page-break-after: avoid;
            page-break-before: avoid;
        }
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adam G.
  • 147
  • 2
  • 2
6

Set display:none for all other elements which are not for prints.

Setting visibility:hidden will keep them hidden, but they all are still there and have taken space for them. The empty page is for those hidden elements.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Janaka R Rajapaksha
  • 3,585
  • 1
  • 25
  • 28
  • 2
    Thx, if you have dynamic content you can use the `:not` selector to set everything to `display: none` but not the print-class, like `body > :not(.print) { display: none !important; }` – Putzi San Dec 30 '20 at 07:42
5

I had a similar issue but the cause was because I had 40px of margin at the bottom of the page, so the very last row would always wrap even if there were room for it on the last page. Not because of any kind of page-break-* css command. I fixed by removing the margin on print and it worked fine. Just wanted to add my solution in case someone else has something similar!

AlexMorley-Finch
  • 6,785
  • 15
  • 68
  • 103
5

If you just want to use CSS and want to avoid a page break, then use

.print {
    page-break-after: avoid;
}

Take a look at paged media.

You can use scripting equivalents for pageBreakBefore and pageBreakAfter and can dynamically assign their values.

For example, instead of forcing custom page breaks on your visitors, you can create a script to make this optional. Here I'll create a checkbox that toggles between slicing the page at the headers (h2) and at the printer's own discretion (default):

<form name="myform">
    <input type="checkbox" name="mybox" onClick="breakeveryheader()">
</form>

<script type="text/javascript">
  function breakeveryheader() {
    var thestyle = (document.forms.myform.mybox.checked) ? "always" : "auto"
    for (i=0; i<document.getElementsByTagName("H2").length; i++)
      document.getElementsByTagName("H2")[i].style.pageBreakBefore = thestyle
  }

Click here for an example that uses this. You can substitute H2 inside the script with another tag, such as P or DIV.

http://www.javascriptkit.com/dhtmltutors/pagebreak.shtml

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bilash.saha
  • 7,226
  • 2
  • 35
  • 40
4

It seems there are a lot of possible causes, with the likely theme being that the body tag ends up with a height that is considered too large for whatever reason.

My cause: min-height: 100% in a base style sheet.

My solution: min-height: auto in a @media print directive.

Note, auto didn't seem to be a correct value, according to PhpStorm. However, it is correct according to Mozilla's documentation on min-height:

auto
The default minimum size for flex items, providing a more reasonable default than 0 for other layouts.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
George Marian
  • 2,680
  • 20
  • 21
  • I just put 'min-height:initial !important;' and it worked for me. – Siby Thomas Sep 07 '16 at 09:51
  • @SibyThomas I avoid the !important declaration if at all possible. It makes things more difficult for overriding properties. I didn't even consider `initial` since I assumed it'd be problematic for dynamically sized elements. Note that the initial value is 0, so I still assume that `auto` is generally more useful. – George Marian Sep 07 '16 at 19:21
4

Chrome seems to have a bug where in certain situations, hiding elements post-load with display:none, leaves a lot of extra space behind.

I would guess they are calculating document height before the document is done rendering. Chrome also fires two media change events, and doesn't support onbeforeprint, etc. They are basically being the Internet Explorer of printing. Here's my workaround:

@media print {
    body {
        display: none;
    }
}

body.printing {
    display: block;
}

You give body class="printing" on document ready, and that enables the print styles. This system allows for modularization of print styles, and in-browser print preview.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dirigible
  • 1,749
  • 16
  • 11
  • This fixed my problem. I was printing an IMG and setting the style to "display: block;" prevented the second blank page. – kyletme Jan 12 '21 at 23:51
4

I changed the CSS display and width properties of the print area:

#printArea {
    display: table;
    width: 100%;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Afshin Razaghi
  • 410
  • 4
  • 10
4
.print:last-child{
    page-break-after: avoid;
    page-break-inside: avoid;
    margin-bottom: 0px;
}

This worked for me.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
guest
  • 41
  • 1
3

In my case, setting width for all divs helped:

.page-content div {
    width: auto !important;
    max-width: 99%;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Marjanus
  • 31
  • 2
2

After struggling with various page-break settings and heights and a million various CSS rules on the body tag, I finally solved it over a year later.

I have a div which is supposed to be the only thing on the page which prints, but I was getting several blank pages after it.

My body tag is set to visibility:hidden;, but that wasn't enough. Vertically tall page elements still take up 'space'. So I added this in my print CSS rules:

#header, #menu, #sidebar{ height: 1px; display: none;}

to target specific divs by their ids which contain tall page layout elements. I shrunk the height and then removed them from the layout. No more blank pages. Years later I'm happy to tell my client I cracked it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sherri
  • 816
  • 2
  • 9
  • 18
  • Yes if you use `visibility: hidden;` it will still take up space. If you use `display: none;` the space will be removed. At that point you won't need to specifically set the height, just FYI. – chapeljuice Nov 22 '16 at 23:01
2

Strangely, setting a transparent border solved this for me:

@media print {
  div {
    border: 1px solid rgba(0, 0, 0, 0)
  }
}

Maybe it will suffice to set the border on the container element. <- Untested.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
alexloehr
  • 1,773
  • 1
  • 20
  • 18
2

I was also getting extra blank pages, and the only thing that worked for me was adding this rule to my CSS content (for print):

*
{
    box-sizing: border-box;
}

Then I no longer need to worry about having an extra pixel added when using margin, padding or border.

Once I've added that rule, I only had to adjust the boxes positions and everything worked flawlessly.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matías Cánepa
  • 5,770
  • 4
  • 57
  • 97
1

Add this CSS content to the same page to extend the CSS file.

<style type="text/css">
   <!--
   html, body {
    height: 95%;
    margin: 0 0 0 0;
     }
   -->
</style>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
  • Why the ``? It seems like something that is only required for very old browsers, like [Internet Explorer 6](https://en.wikipedia.org/wiki/Internet_Explorer_6)(?). – Peter Mortensen Aug 18 '23 at 14:21
1

I tried all solutions, but this worked for me:

<style>
    @page {
        size: A4;
        margin: 1cm;
    }

    .print {
        display: none;
    }

    @media print {
        div.fix-break-print-page {
            page-break-inside: avoid;
        }

        .print {
            display: block;
        }
    }

    .print:last-child {
        page-break-after: auto;
    }
</style>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paulo Weverton
  • 372
  • 3
  • 7
1

I just encountered a case where changing from

    </div>
    <script src="addressofjavascriptfile.js"></script>
</body>
</html>

to

        <script src="addressofjavascriptfile.js"></script>
    </div>
</body>
</html>

fixed this problem.

Terry Horner
  • 497
  • 6
  • 16
1

First, emulate the print stylesheet via your browser's devtools. Instructions can be found here.

Then you'll want to look for extra padding, margin, borders, etc that could be extending the dimensions of your pages beyond the 8.5in x 11in. Pay special attention to whitespace as this will be impossible to detect via the print preview dialog. If there is whitespace that shouldn't be there, right-clicking and inspecting the element under the cursor should highlight the issue (unless it's a margin causing it).

Kevin Beal
  • 10,500
  • 12
  • 66
  • 92
1

I was also getting an extra space below/above depending upon whether I use

page-break-after: always; or page-break-before: always;

I removed the height and border of the element to which I apply page-break-after or page-break-before.

This helped me in removing that extra page.

For example:

/* The element to which we apply page break */
<div class="page-break-line"></div>

Inside styles:

<style>
  .page-break-line {
     /** Make sure you don't give any height,border.
         Because giving them gives an extra page.
     */
     visibility: hidden;
  }

  @media print {
    /* This is the important to add page break! */
    .page-break-line {
      page-break-before: always !important;
    }
  }
</style>

Note: A div with page-break-line is kept beneath each of my row which I need to print separately.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
adi
  • 984
  • 15
  • 33
0

None of the answers worked with me, but after reading all of them, I figured out what the issue was in my case.

I had one HTML page that I want to print, but it was printing with it an extra white blank page. I am using AdminLTE, a Bootstrap 3 theme for the page of the report to print, and in it the footer tag I wanted to place this text to the bottom right of the page:

Printed by Mr. Someone

I used jQuery to add that text instead of the previous "Copy Rights" footer with

$("footer").html("Printed by Mr. Someone");

And by default in the theme, the tag footer uses the class .main-footer, which has the attributes:

padding: 15px;
border-top: 1px solid

That caused an extra white space, so after knowing the issue, I had different options, and the best option was to use

$("footer").removeClass("main-footer");

Just in that specific page.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

Put the stuff you need on a page in a div and use page-break-inside:avoid on that div.

Your div will stay on one page and go onto a second or third page if needed, but the next div, should it have to do a page break, should start on the next page.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

Check if there is any white space after the html tag at the bottom. Removing any whitespace below helped me.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Wahsei
  • 289
  • 2
  • 6
  • 16
0

The extra page problem in my case was caused by table element on the page. I tried many of the solutions offered here, but to solve the problem I had to change the table CSS content to:

table {
    width: 99%;
    height: 99%;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JessieinAg
  • 355
  • 3
  • 10
0

First off, if you don't know of this trick, it helps. You can preview print pages with the inspector. Click the three dots in the top right, then "More Tools""Rendering". Now navigate to the Rendering tab, and you can emulate the CSS media type "Print". Very useful!

I took the advice of Michael Radionov's answer and added a border to all my elements. I gave html, main, and body different border colors, and I noticed that my html and body was surrounding my unwanted extra page at the end.

The trick to use html, body { height: auto; } or html, body { height: 99%; } didn't work for me, but setting

html, body { height: max-content }

worked for some of my print pages.

Something else that seemed to cause an issue was padding-bottom or margin-bottom being applied to my container elements. This pushed html, body, and main tags outside the page bounds and created a new page. So resetting those property values as well with

main, .master, .content { margin: 0; padding: 0 }

worked for the rest of my print pages.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kim Skogsmo
  • 441
  • 3
  • 13
0

In my case I'm giving a margin-top a div which is causing that issue of blank page printing. I removed that margin and the issue went away.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
habib
  • 1,454
  • 17
  • 31
0

Below is our all of the elements or components that we want to apply page break.

<!-- our all components as JSX/TSX -->
<React.Fragment >
<Container ref={componentRef as any}>
 <PageOne />
 <PageTwo />
</Container>
</React.Fragment >

<!-- our all components as HTML -->
<div className="container" ref={componentRef as any}>
 <div className="page-break">page one</div>
 <div className="page-break">page two</div>
</div>

Now let's create a style file called style.css OR index.css (whatever you want) and add this code

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

@media print {
  @page {
    size: A4;
    margin: 20px;
  }
  .page-break {
    page-break-before: always !important;
  }
}

This code is enough to solve this issue

Not required, I just mentioned here my printHandler

const componentRef = useRef();
const handlePrint = useReactToPrint({
  content: () => componentRef.current as any,
  documentTitle: "Astrology",
  removeAfterPrint: true,
  onBeforeGetContent: () => setLoading(true),
  onAfterPrint: () => {
    setLoading(false);
    toast.success("PDF save successfully");
  },
});
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
0

I was able to debug this issue by adding a red background color to every div, then rendering the print version in the rendering tab of chrome dev tools.

I first added this CSS:

@media print {
  div {
    background-color: red;
  }
}

Then opened the rendering tab and set CSS emulation to print:

Chrome dev tools rendering tab

Then I saw red at the bottom of the page that was caused by a margin on my main element.

Now I'm honestly not sure if this was the real root cause fix of the issue, but at least this method of debugging the issue I think is worth the answer :)

Shahin Dohan
  • 6,149
  • 3
  • 41
  • 58
0

Using absolute positioning, pull up the content you need on the page:

@media print {
    .content {
        position: absolute;
        top: 0;
    }
}
Alexander Abashkin
  • 1,187
  • 4
  • 13
  • 18
-1
@media print {
        .print-page {
            display: block;
            height:900px;
        }
    }
Abhishek Kanrar
  • 418
  • 4
  • 6