logo

Printing with Page Breaks

Following my article a week or so ago about controlling printing using CSS I received quite a few mails asking me about whether we can use page-breaks when printing on the web. Not quite sure what the link between the two is but all the same it appears this is a topic that needs discussing.

You can indeed control page-breaks on the web, assuming, that is, you are using IE4+ or OP5+. Level 2 of the CSS Specification defines two attributes: page-break-before and page-break-after. We could use either to do the job but I shall look at using the latter. Before we start take a look at this page in Print Preview mode (you could also print the page but i wouldn't want to advocate such a waste of paper). Notice that everything after this paragraph starts on a separate page.


How did I do that:

The above paragraph starts with the following HTML:

<div style="page-break-after:always;">You can indeed....

This "styling" tells the browser that as soon as that paragraph finishes everything after it should start printing on a new page. We could just as well apply the same rule to, say, all the paragraphs on a page by adding the following to its header:

p {
page-break-after : always;
}

However, it's is more likely that you will want to apply breaks only after certain elements rather than after every paragraph. That's why it is probably better to apply the style individually or to a set of elements that you can use selectively like the DIV.

What about a useful example:

Let's take an example of a Notes form where using this method might be more than just for the sake of it. Consider a form that contains lots of information which can be divided in to separate sections. Your user probably wants to have each part start printing on a separate page. I'm going to use the example of a financial report for a fiscal year (I'm working at a bank at the moment) where each quarter's report should start on a new page. Probably the easiest way to do this is to place each quarter report in to a separate DIV element. We can then define the style for the DIVs so that each one has a page-break after it. First thing to do is add this CSS to the "HTML Header" ($$HTMLHead) on the form:

div {
page-break-after : always;
}

Let's assume that each quarter's report is in a separate Rich-Text field and that the form consists of a general information header and then the four fields. We need to split these fields apart using some Pass-Thru HTML that wraps them each inside a separate DIV element. When done the form would look something like the one shown below:

image

When a document using this form is viewed on the web it will display each section in a new DIV and when these get printed they are on separate pages. All of this will, of course, be invisible to the user.

Now let's get really clever:

What if some of your users want to print pages with the page-break and some want to print them without? You know what they are like! Well, we can always give them the option. Using the pageBreakAfter property of an element we can use JavaScript to toggle between breaking and non-breaking. The following function loops through all the elements and turns page-breaks on or off depending on an argument passed to the function. It then takes another argument passed in and decides whether or not to print the document.
function togglePageBreakAfter( ){
divs = document.getElementsByTagName(arguments[0]);
for (var i=0; i < divs.length; i++ ) {
div = divs[i];
div.style.pageBreakAfter = (arguments[1]) ? "always":"";
}
if ( arguments[2] ) window.print();
}
Try it out using the links below to turn breaks on and off and/or print the page:

Turn On: JavaScript:togglePageBreakAfter('DIV', true);
Turn Off: JavaScript:togglePageBreakAfter('DIV', false);
Turn On + Print: JavaScript:togglePageBreakAfter('DIV', true, true);
Turn Off + Print: JavaScript:togglePageBreakAfter('DIV', false, true);

So there you go. Now you can really impress your boss/colleagues....

Further Reading:

Have a look at Microsoft's Documentation on this attribute.

Scott Andrew's page about scripting browsers that comply with the DOM standards.

Feedback

    • avatar
    • Ben
    • Tue 11 Sep 2001

    What about the other DIV elements?

    This example is great, and I've already developed a form using it, but what about when Domino generates it's own DIV tags, like in Tables for instance. Every row would be placed on a new page. Is there an easy way to get around this?

    1. Good question...

      I wasn't aware that Domino used <div> tags when it creates tables.

      To get more control you can redefine the style to: [<span class="CSS">] div.onlyMyDivs{ page-break-after : always; } [</span>] Which tells the browser only to apply this to <div>s with the "onlyMyDivs" class assigned.

      So no you create your divs like this: [<span class="html">] <div class="onlyMyDivs">My content<div> [</span>] HTH Jake

      Show the rest of this thread

  1. Getting pagebreaks to work in a view

    How could you make this work within a view?

      • avatar
      • Kamal
      • Tue 12 Mar 2002

      RE:Getting pagebreaks to work in a view

      ( I think) you'd have to include the CSS in the $$ViewTemplate and add the div code to the last column of the view OR the column/position where you need a page break.

    1. Re: Getting pagebreaks to work in a view

      To do this, you need to include some code in whatever column formula is appropriate. Personally, I have knocked regular views on the head as they never line up right. My web views are just one or two columns (if it's categorised) and the second column contains all the html to write out a complete row of the view, and do a check for a page throw at the end of each line.

      Like this, inside a column formula:

      DBPath:= "\\" + @ReplaceSubstring( @ReplaceSubstring( @Subset( @DbName; -1); "\\"; "/"); " "; "+");.... Yada Yada... declaring all the widths of the <TDs> and stuff...

      Blahdy Blah... now (whilst still in the column formula, declare (but not make) a call to a function checkRow in the JS Header of the document containing this view...

      check_break:="<SCRIPT>checkRow(" + @DocNumber("") + ")</SCRIPT>";

      (NB the ("") param to @DocNumber makes sure it only passes the RHS doc number, even in a categorised view. This is your FREE line count!)

      Now chuck out a line of the view as the return value for the column formula:

      "[[<!-- ignore -->]</NOSCRIPT>" + "<TR VALIGN=top>" + "<TD><SPAN style=\"WIDTH:85px; overflow:hidden\"><FONT SIZE=1 FACE=\"Verdana\">" + FldDateOfDuty.... blah...

      "<NOSCRIPT>" + check_break + "]"

      The inclusion of check_break in this string causes the checkRow function to be called:

      function checkRow(count) {

      if (count % LinesPerPage == 0) // time to throw page { document.write(ThrowPage + PageTopSimple); PageCount++; } }

      where (declared in JS Header of form including this view):

      LinesPerPage is a var in the JS header, set to whatever you need.

      var ThrowPage = "<DIV STYLE=\"page-break-before:always\"></DIV>";

      var PageTopSimple = "<TR><TD><HR></TD></TR>";

      Obviously, my page top is really more than a simple <HR>, it's acutally a knack-off string describing all the table headings, but you get the idea.

      Show the rest of this thread

  2. Page Break

    Dear Sir, I have printed totally 10 pages. but 3rd page does not display. 3rd is empty. please solve my problem.

    saravanan.

  3. I have a question on page-breaks

    Hi,

    I have a question on page-breaks. Our product creates a HTML report using CSS and DIV tags such that each row/element gets positioned at a particular place in the html output. Say for example, in header I define DIV.C16678128 {z-index: 3; left: 2.967in; width: 0.700in; height: 0.163in; text-align: right;} and in the body I will have <DIV class="C16678128"; style="top: 0.607in; left: 3.342in; width: 0.700in; height: 0.169in;"> 107 </DIV>. But the problem I am facing is with this output I see that the while printing the last row of each page gets partially rendered on page 1 and partially on page 2. I tried your suggestion but did not work for me. Any inghts on this will be greatly appreciated. I can send you the HTML file if you need.

    Your prompt response is greatly appreciated.

  4. Page Break: exclude Window.Title

    window.print() seems to always print the window.title as well as the window.status bar at the bottom. Is there a way to turn that off? Thanks - and great thread. Really helpful.

      • avatar
      • kumar
      • Tue 21 Oct 2008

      Re: Page Break: exclude Window.Title

      on firefox, go to page setup --> margins and footers and select your print options. Not sure on IE

  5. Printing with Page Breaks

    After applying page break, I get one another blank page in print view. How can I avoid this blank page to print?

    1. Have you been able to figure out how to prevent the blank page at the end?

  6. Print with page breaks

    How can I make a printer start printing from a certain point on a page. For example I don't want the page's header/banner to be printed so how can I instruct the printer to start printing from just below the banner/header?

    Awestruck

  7. Print a table

    How I can print a table with Page Breaks. So if there is no space for the last row in the page it transfers to the next page and print the table header again in every page?

    1. 3tables?

      how about if i want 3 tables on one sheet of paper then the next 3 tables on the next bit of paper and so on? i have a loop you see...

    2. This is the behemoth I have been working on for a while and here is my response: You have to guess-timate. The problem starts with the very bad coverage HTML has for printers. In fact - there is none. So to begin with you have to guess as to the setup of the printer. I assume 8.5x11 paper with a one(1) inch margin on all four sides giving you only 6.5x9 inch paper. Most printers print at 300dpi now-a-days. HOWEVER! HTML automagically will convert your point size(PTs) to print correctly on a printer - but that will completely muck-up most of what you are trying to do. Why? Because each printer prints slightly differently and so what will work on one - will not on another. (Or it will kind-of work.)

      There is an excellent website called (if I remember correctly) www.linotypist.com where the person discusses printing problems in HTML. His first suggestion is:

      Begin CSS:

      html {

      font-size: 62.5%;

      }

      End CSS:

      This weird number causes all printers to make 1em = 10px. My suggestions in addition to this is to wrap your entire output in a table with a single TD inside of it. Like so:

      Begin HTML:

      <table style='table-layout:fixed;'>

      <tbody>

      <tr>

      <td valign='top'>

      End HTML:

      The "table-layout:fixed;" causes whatever you write out to the printer to be "fixed" (as in width and placement). The "valign='top'" on the TD statement ensures that your printouts always start at the top of the page. This IS important.

      My next suggestion is to have two - SEPARATE - style sheets. One for the printer and one for the screen. Like so:

      Begin STYLE:

      <style media='print'>

      [Put in your styles for the printer]

      </style>

      <style media='screen'>

      [Put in your styles for the screen]

      </style>

      End STYLE:

      The reason is - you can then hide things on the printer/screen as you need to so you can concentrate on just that medium. Mixing and matching is no where near as good as you can mistakenly combine what is to go only to the printer with what is to go to the screen. By keeping them separate you stand a better chance of getting everything right.

      My next suggestion: Count lines and pages. Just like in the 1970's when there was no page control - there really isn't any kind of page control in HTML today. You would have thought that W3C would give as much consideration to printing as they do just showing stuff on the screen - but no. They do not. So you need to keep track of how many lines you have printed and how many pages. You can do this if you use something like PHP to generate the web page and just count everywhere you either do a <BR>, <P>, or <TR> (in a table). If you are going to use DIVs or some other positionable element, then (in PHP) do a wordwrap() on the text to be displayed. However many lines come back in the array is approximately however many will be used when printing.

      My last suggestion is NEVER use the <P> command to do a page eject. Why? Because <P> always puts at least one blank line (if not two sometimes) on your page. These "hidden" newline commands will throw off your counting of lines. Instead, use this:

      Being HTML:

      <hr style='width:0px;height:0px;page-break-after:always;'>

      End HTML:

      This will not use any space on your page and always do a page break after it. (Or you can use page-break-before:always - it doesn't really matter which you use.)

      I hope this helps.

  8. Multiple value fields

    Thsi gets a little more challemginmg with a multiple value field: Say you perform an @DbLookup and want to generate a new page after each element is printed - the browser seems to totally ignore the "pagefeed ****" instruction completely!

    Any ideas, Jake?

    • avatar
    • Tony
    • Fri 25 Jun 2010

    Brilliant. Thank you. This was just what I needed.

    Used with a css media="print" which just removes elements not required and sets up the body. I can now apply page breaks where appropriate.

    /* get rid of background color and set font */

    font-family: Times New Roman, serif; font-size: 12px; line-height:1.3;

    padding:0; margin:0;

    background-color: #fff;

    color:#000;}

    /* Get rid of navigation and left column */

    #leftcolumn {display:none; }

    .navigation {display:none; }

    /* Move the content column back to the left */

    #contentcolumn {margin-left: 0;}

  9. Thanks Mark

    This problem was driving me potty!

    <hr style='width:0px;height:0px;page-break-after:always;'>

    worked a treat for me

    • avatar
    • Steve
    • Fri 6 Aug 2010

    How about if i want to include a 'footer' (like a message or copyright) before the page break, but have it be at the bottom of the page?

    ps, no i do not want to use the browser to do this. :)

  10. Does any one know, how to avoid page-breaking inside a paragraph. I would like browser to move whole paragraph to the next page if it doesn't fit into the first one.

    W3C standard is:

    {page-break-inside: avoid;}

    But this is supporte only by Opera. Anyone know how to make it work in FF and IE?

    • avatar
    • Ambily
    • Wed 18 May 2011

    Thank you so much. This is exactly what i want :D

    • avatar
    • Shamir
    • Thu 23 Jun 2011

    Thanks a lot Mike.. it resolved my issue too

    <hr style='width:0px;height:0px;page-break-after:always;'>

  11. In printview:

    On the first page all references to the right are ok, after first page-break all following references are only on the same place on the top of the first page! I use Mozilla Firefox V8

    I have in vain tried @media print.

    I am not a professional web-builder.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:



Navigate other articles in the category "Forms"

« Previous Article Next Article »
Control what gets printed from the web   Storing lots of input fields in one list

About This Article

Author: Jake Howlett
Category: Forms
Keywords: CSS; style; print;

Options

Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »