16

I want to print 30 pages with some data on top and some data on bottom. My code looks like:

<...>



<div style="page-break-after: always">
    <div>This should be on top1</div>
    <div>This should be on bottom1</div>
</div>
<div style="page-break-after: always">
    <div>This should be on top2</div>
    <div>This should be on bottom2</div>
</div>


<etc>

I tried everything:

  • Positions: relative (no change), absolute (footer on first page only), fixed (on last page only)
  • Setting html, body, each div height to 100%. No idead why should I do this. Did not change anything

Maybe there is a way to force my browser (FF) to stick div to bottom of page?

peku33
  • 3,628
  • 3
  • 26
  • 44
  • Are you talking about printing with an actual printer on to hard copy? I think the best you could do in that situation would require you to know the size of the paper that is being printed too. You can use inches as a unit of measure in CSS. That might help you out. – crush Jan 09 '14 at 22:07
  • 1
    Yes. But my solution must cover any size of paper. – peku33 Jan 09 '14 at 22:08
  • Can you ask the person printing for the dimensions of the paper they are printing too? You could offer it in a drop down box that they select or something. Default to the most common paper size. That's the best I can come up with. Maybe someone else has something better. – crush Jan 09 '14 at 22:09
  • Another option would be to convert your page into PDF, and then have the person print the PDF document. PDF can be scaled fairly well. – crush Jan 09 '14 at 22:10
  • 3
    No, simply i don't want to know the size of the paper. It must work without it. – peku33 Jan 09 '14 at 22:10
  • Will it always be 30 pages printed? – Arthur Weborg Jan 09 '14 at 22:32
  • Not always. From 1 to infinity – peku33 Jan 10 '14 at 11:22

4 Answers4

21

Finally found an answer:

  1. html,body MUST HAVE height: 100%;
  2. There should be two types of div: outside (size of page), footer
  3. For both set display: block;
  4. For the outside set height: 100%; position: relative;
  5. For the inside set position: absolute; bottom: 0px;

Voila!

Here is my complete code:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <style>
        html,body
        {
            height: 100%;
            margin: 0px;
        }
        body > div
        {
            height: 100%;
            display: block;
            position: relative;
        }
        body > div > div
        {
            position: absolute;
            bottom: 0px;
            left: 0px;
        }
    </style>
</head>
<body>
    <div>
        Page1
        <div>Page1Footer</div>
    </div>
    <div>
        Page2
        <div>Page2Footer</div>
    </div>
    <div>
        Page3
        <div>Page3Footer</div>
    </div>
</body>
</html>
Rana Soyab
  • 898
  • 5
  • 20
peku33
  • 3,628
  • 3
  • 26
  • 44
9

Update I played around a little bit with the code above and this may work easier than what I initially thought. (Note, there is potential for the footer to overlap content from the previous div, this could be resolved by adding a margin-bottom attribute to the content div equal to your custom footers set height - Also, if your page content is too long between page breaks, this will still have a couple scenarios that need attending). All that said, I tested locally and it worked as you desired.

CSS

<style>
@media print{
    .footer{
       position:relative;
       top:-20px; // this sets the footer -20px from the top of the next 
                  //header/page ... 20px above the bottom of target page
                  //so make sure it is more negative than your footer's height.

       height:10px;//notice that the top position subtracts 
                   //more than the assigned height of the footer
    }
}
</style>

HTML

<body>
   <div style="page-break-after: always">
      <div>This should be on top1</div>
   </div>
   <div style="page-break-after: always">
      <div class="footer">This should be on bottom of page1</div>
      <div>This should be on top2</div>
   </div>
   <div class="footer">This should be on bottom of page2</div>
</body>


Original Answer

Unfortunately there is no easy way to do this. Browsers do not offer a means of creating custom headers and footers for printing.

Your best bet is to place information you want on every page in the title tag found in the <head><title>YOUR COMMON CONTENT</title></head> It's not going to be the prettiest. It comes down to your requirements.

The other option is to use @media print (CSS) coupled with javascript to dynamically calculate and insert page breaks/gaps of white-space while inserting divs(your custom footer and or header) at absolute positions for the known paper size. Then after the print event dynamically change the format back.

Arthur Weborg
  • 8,280
  • 5
  • 30
  • 67
  • Is there any way to calculate the height of page while printing? – peku33 Jan 09 '14 at 22:18
  • You can calculate the cumulative height of your dom elements [how to calculate height](http://stackoverflow.com/questions/526347/css-javascript-how-do-you-get-the-rendered-height-of-an-element). It might get complicated though, depending on what you are printing. – Arthur Weborg Jan 09 '14 at 22:27
  • I gave it some more thought, changed my mind and have an easier solution, I tested locally and it worked. – Arthur Weborg Jan 09 '14 at 23:58
  • Sad, but your Update is not working for me... Footers seems to be not present at all. – peku33 Jan 10 '14 at 11:26
  • Please forgive me, I tested on Chrome and just tried it in FireFox (which worked on Chrome, but not firefox). Glad you found a solution that works for you. – Arthur Weborg Jan 10 '14 at 15:39
1

If you use the and elements for your header and footer

thead   {display: table-header-group;   }

tfoot   {display: table-footer-group;   }

Source: http://www.codeproject.com/Questions/247645/Print-html-table-into-A4-size

JerryHuang.me
  • 1,790
  • 1
  • 11
  • 21
1

This works for me

Just add following css in your html file

@page {

        margin-bottom: 40px;
        counter-increment: page;

        @bottom-right {
            border-top: 1px solid #000000;
            padding-right:20px;
            font-size: 12px !important;
            content: "Page " counter(page) " of " counter(pages);
        }
        @bottom-left {
            content: "Footer content goes here.";
            border-top: 1px solid #000000;
        }

    }
Sergey Kudriavtsev
  • 10,328
  • 4
  • 43
  • 68
jaydip jadhav
  • 477
  • 4
  • 5
  • 4
    Downvoted because this isn't currently supported by any browsers. – Greg May 20 '19 at 15:32
  • 1
    I have no idea how this works for you given that every browser in https://caniuse.com/#search=Page-margin%20boxes is red. – flaviut Jan 30 '20 at 18:32
  • While not supported by browsers, this is supported e.g. by python's [weasyprint](https://github.com/Kozea/WeasyPrint) library, [example](https://github.com/CourtBouillon/weasyprint-samples/blob/master/invoice/invoice.css#L16) – vlz Jun 01 '22 at 13:36