Print page numbers on pages when printing html
Asked Answered
B

11

103

I've read a lot of web-sites about printing page numbers, but still I couldn't make it display for my html page when I try to print it.
So the CSS code is next:

@page {
  margin: 10%;

  @top-center {
    font-family: sans-serif;
    font-weight: bold;
    font-size: 2em;
    content: counter(page);
  }
}

I've tried to put this page rule inside

@media all {
    *CSS code*
}

And outside of it, tried to put it in @media print, but nothing helped me to display the page numbers on my page. I've tried to use FireFox and Chrome(based on WebKit as you know). I think the problem is in my html or css code.
Could somebody show me an example of implementing this @page rule in the big html page with several pages? I just need the code of html page and the code of css file, that works.
P.S. I have the latest supported versions of browsers.

Bangalore answered 18/11, 2013 at 15:2 Comment(4)
possible duplicate of Page numbers with CSS/HTMLBimetallism
@James Donnelly Well the questions are simmilar, but I have an answer here for my question, as I did it.Bangalore
Try this: How to number print pages?Kazimir
currently, manually implementing something like Rul seems to do in this question stackoverflow.com/questions/16297619 seems to be the only feasible way....Auricular
B
80

As @page with pagenumbers don't work in browsers for now I was looking for alternatives.
I've found an answer posted by Oliver Kohll.
I'll repost it here so everyone could find it more easily:
For this answer we are not using @page, which is a pure CSS answer, but work in FireFox 20+ versions. Here is the link of an example.
The CSS is:

#content {
    display: table;
}

#pageFooter {
    display: table-footer-group;
}

#pageFooter:after {
    counter-increment: page;
    content: counter(page);
}

And the HTML code is:

<div id="content">
  <div id="pageFooter">Page </div>
  multi-page content here...
</div>

This way you can customize your page number by editing parametrs to #pageFooter. My example:

#pageFooter:after {
    counter-increment: page;
    content:"Page " counter(page);
    left: 0; 
    top: 100%;
    white-space: nowrap; 
    z-index: 20;
    -moz-border-radius: 5px; 
    -moz-box-shadow: 0px 0px 4px #222;  
    background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);  
  }

This trick worked for me fine. Hope it will help you.

Bangalore answered 1/12, 2013 at 21:59 Comment(12)
@donvin this does not seem to work in IE11. The counter is never incremented.Precedential
@Precedential Well, I didn't try IE11, but if you wiil find the way to do it in IE11, you could write an answer here.Bangalore
counter-increment should work since IE8 : developer.mozilla.org/en/docs/Web/CSS/counter-incrementGeter
I tried the above code. Am using Chrome 54. It just sets 1 page number through out all the pages (eg. Page 1 on all pages). The increment does not work. I tried putting counter-increment for various elements (eg. page-break:before, @page, etc), however in all cases it just prints 1 page number (eg. Page 1 on all pages). Any help here will be appreciated.Predictor
When I try this, I only get Page 1 at the bottom of the last page. How frustrating you can't use the CSS3 standards from 2013; jeesh.Norwood
I suspect it never really increments because while it is shown on every page it's still one and the same element.Cherri
It seems that support for CSS Paged Media is starting to appear in some major browsers. caniuse.com/#feat=css-paged-mediaWillianwillie
I move counter-increment: page to the CSS selector for the element and not the pseudoelement :after and kept the content: counter(page) in the :after selector. It worked in Chrome 71, Safari 12, not sure about other browsers.Deepseated
this code does increment for me but is showing only in the last page of pdf like page 3 only in the last 3rd pageRudbeckia
need add ``` body { counter-reset: page; } ```Mesomorphic
None of the above solutions worked for me on Chrome.Orna
You need to have different element for each increment. Instinct would be to create a fixed footer, and that's when it does not increment, because you just increment once. You need to use a different footer every time. You can't use position: fixed;, because then they would just stack. As an example, you could increment for each <section></section> and then after each section you could add a <div class="page-count"></div> and the class would contain content: "Page " counter(page);.Obloquy
F
50

Try to use https://www.pagedjs.org/. It polyfills page counter, header-/footer-functionality for all major browsers.

@page {
  @bottom-left {
    content: counter(page) ' of ' counter(pages);
  }
}

It's so much more comfortable compared to alternatives like PrinceXML, Antennahouse, WeasyPrince, PDFReactor, etc ...

And it is totally free! No pricing or whatever. It really saved my life!

Flocculus answered 25/3, 2020 at 21:20 Comment(5)
This is fantastic, spent ages trying to get this working and THIS was the most lightweight thing, don't know why this isn't further up the answer list! All the other stuff seems to be deprecated by major browsers these days :(Vanscoy
Oh wow, i just added the script link + the sample css and it's already giving me way better results than anything i have tried before. Definitely worth looking into!Fredel
Only issue is that it applies your @media print styles ALL the time - even when outside of print css context. This might not be desirable if you want to have one view for print and another for regular browser viewing.Dg
@Dg Maybe you can try not to include pagedjs for regular browser-viewing?Schafer
@Dg you need to put window.PagedConfig = { auto: false }; in a script tag. And when you want to print you need to call await window.PagedPolyfill.preview(); window.print();. I've put a demo code here https://mcmap.net/q/211921/-how-to-force-chapters-to-start-on-odd-pages-html-and-epubActivity
Z
30

This javascript will add absolute positioned div's with pagenumbers on the right bottom corner and works in all browsers.

A4 height = 297mm = 1123px(96dpi)

<html>
    <head>
        <style type="text/css">
            @page {
              size: A4;
              margin: 0; 
            }

            body {
              margin: 0;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript">
          window.onload = addPageNumbers;

          function addPageNumbers() {
            var totalPages = Math.ceil(document.body.scrollHeight / 1123);  //842px A4 pageheight for 72dpi, 1123px A4 pageheight for 96dpi, 
            for (var i = 1; i <= totalPages; i++) {
              var pageNumberDiv = document.createElement("div");
              var pageNumber = document.createTextNode("Page " + i + " of " + totalPages);
              pageNumberDiv.style.position = "absolute";
              pageNumberDiv.style.marginTop = "calc((" + i + " * (297mm - 0.5px)) - 40px)"; //297mm A4 pageheight; 0,5px unknown needed necessary correction value; additional wanted 40px margin from bottom(own element height included)
              pageNumberDiv.style.height = "16px";
              pageNumberDiv.appendChild(pageNumber);
              document.body.insertBefore(pageNumberDiv, document.getElementById("content"));
              pageNumberDiv.style.left = "calc(100% - (" + pageNumberDiv.offsetWidth + "px + 20px))";
            }
          }
        </script>
        <div id="content">
            Lorem ipsum....
        </div>
    </body>
</html>
Zymolysis answered 17/11, 2020 at 22:3 Comment(10)
hi @Ousama can you give your template?Truck
when you are printing remove default margin added by the browsers.Truck
I used this solution and it worked great. A small change I made was to do window.onbeforeprint instead of window.onload to get the page numbers on the print, but not otherwise.Lawson
also remember to cleanup after print by adding a funciton and triggering with window onafterprint: window.onafterprint = removePageNumbers;Necessitate
for me only working solution in angular 13. Thanks so far!Lowgrade
What changes would I need to do if I want to add some margin?Antisepticize
Thanks so much great work. I will try modify this function to work with table header. because. thead tag will be repeated each page, and your function works on the size of the page so, it needs extra work :).Recipe
@MichaelDimmitt please can you share the removePageNumbers function?Beitch
Add page numbers puts "# of pages" as divs above the body then uses absolute positioning to place them on the pages. The cleanest way to remove those elements would be to put all of those divs in a single container that is positioned absolute. With a unique id. and then the remove script gets that container element by id and calls .remove() . Hope that helps.Necessitate
Only thing that worked for me - thanks! Full example here: dirkk0.neocities.org/printcssJaleesa
H
6

Can you try this, you can use content: counter(page);

     @page {
       @bottom-left {
            content: counter(page) "/" counter(pages);
        }
     }

Ref: http://www.w3.org/TR/CSS21/generate.html#counters

http://www.princexml.com/doc/9.0/page-numbers/

Harriet answered 18/11, 2013 at 15:4 Comment(5)
This is no longer supported by major browsers :(Precedential
@Krish R, Seems you can help me. Look at this : #43951103Hyperpyrexia
Just found out, that if the stylesheet is linked via href, this works for me, if I declare such a code as style tag inside the html header, it doens't. Really wired for me, hope it helps someoneChamness
This works for me using WeasyPrint (PDF generation tool).Schliemann
As of 2019, this still does not work in CSS3. This is not a solution!Capon
A
1

I don't know if someone still out there needs the answer, try this, it might work for you in your html file put a div element your html like this

<div class="page-number"></div>

and do your css like this

.page-number:before {
content: "Page: " counter(page);}

hope it works for you

Aphorism answered 20/5, 2021 at 15:58 Comment(2)
for newest version of chrome, page number is always 0 even in the print screen.Lowgrade
You are attempting to use two different features of CSS in combination to achieve what the OP asked. Sadly, as @Mar Tin pointed out, there is much more to it to make it work, specifically, you have to increment initialize and then increment your counter. You just retrieved it but did not manipulate it. Then there is the matter of positioning it on the page where you want it which is not trivial either. I am going to build a working answer but thank you for pointing me to some of the tools needed to implement it.Manicure
C
0

I know this is not a coding answer but it is what the OP wanted and what I have spent half the day trying to achieve - print from a web page with page numbers.

Yes, it is two steps instead of one but I haven't been able to find any CSS option despite several hours of searching. Real shame all the browsers removed the functionality that used to allow it.

Chelton answered 4/2, 2021 at 19:19 Comment(0)
U
0

If you are looking to add page numbers when printing under Chrome/Chromium, one easy solution is to use Paged.js.

This JS library takes your HTML/CSS and cuts it into pages, ready to print as a book, that you will preview in your browser. It makes the @page and most the CSS3 specifications work for Chrome.

Solution 1 (easy) if you are OK with cutting your view into pages, ready to print

Just add their CDN in the head tag of your page :

<link href="path/to/file/interface.css" rel="stylesheet" type="text/css">

You can then add page numbers by using the automated counter page. Example :

HTML to put anywhere you want to display the current page number:

<div class="page-number"></div>

CSS to make the number appear in the div :

.page-number{
  content: counter(page)
}

The library also allows to easily manage page margins, footers, headers, etc.

Solution 2 (trickier) if you want to show numbers (and page breaks) only when printing

In this case, you need to apply the Paged.js CDN only when printing the document. One way I can think of would be to add a print me button that fires Javascript to :

  1. add the CDN to the page
  2. and then execute window.print(); to launch the printing prompt of the navigator
Ubangi answered 18/3, 2021 at 10:7 Comment(3)
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-restmod/1.1.11/plugins/paged.js"></script> since no one can seem to ever mention the urlLevon
You should refer to the Paged.js website (see hyperlink in the answer above) and use the documentation on how to get started. The CDN mentioned there is not the one you pasted here => see pagedjs.org/documentation/2-getting-started-with-paged.jsUbangi
that website is about as readable as mud. If I ever figure out how to use pagedjs, I'm going to post a detailed step by step do this do that set of instructions for page numbers, because nobody has cared enough to do that, and expecting people to study the equivalent of a small book just to get page numbers is ridiculous. It's just page numbers, for God's sake.Levon
S
0

Above all solution failed in some cases in my code then after researching a while i found this essay way to achieve the desired page number format i wnated in page like1/2, 2/2 if page total page number 2.

1.first declare CSS class and id where you want to print page number:

<p class="page-number" id="pageNumberId"
                                style="font-size: 11px; font-weight: 400; margin: 0;">Page
                                No:</p>
  1. declare it in stylesheet:

<style>

   @page {
            size: A4;
            margin: 1cm;
        }

.bd td, .bd th {
    border: 1px solid #000;
} 
 

    
    
} 

.page-number {
            font-size: 11px;
            font-weight: 400;
            margin: 0;
        }

</style>
  1. then add java script function to update it :

<script th:src="@{/js/jquery-3.6.0.min.js}"></script>
<script type="text/javascript">
        $(document).ready(function(){
            window.onbeforeprint = function() {
                updatePageNumbers();
                
            };
            window.print();
        });
        
        
    
        
        function updatePageNumbers() {
            var pageNumber = 1;
            var totalPageNumber = document.querySelectorAll('.page-number').length;

            document.getElementById('pageNumberId').textContent = 'Page No:' + pageNumber + '/' + totalPageNumber;

            window.addEventListener('beforeprint', function() {
                pageNumber++;
                document.getElementById('pageNumberId').textContent = 'Page No:' + pageNumber + '/' + totalPageNumber;
            });
        }
    </script>

I hope this solution might help somebody ,Thanks.

Santalaceous answered 12/1 at 6:45 Comment(0)
F
-1

I use page numbers styled in CSS to generated PDF documents, and it works:

@page {
    size: A4 portrait;
    margin-top: 1.2cm;
    margin-bottom: 1.2cm;
    margin-left: 1.2cm;
    margin-right: 1.2cm;
    background-image: url('../../images/logo_small.png');
    background-repeat: no-repeat;
    background-position: 40px 10px;
    @bottom-center {
        content: counter(page);
    }
}
Fright answered 26/5, 2022 at 10:35 Comment(0)
U
-2

This is what you want:

@page {
   @bottom-right {
    content: counter(page) " of " counter(pages);
   }
}
Unknown answered 18/11, 2013 at 15:3 Comment(3)
counter(pages) always returns 0 for me, any clues why?Augmentative
Unfortunately, this doesn't seem to be supported in any major browser as of now.Howling
Worked for me in printing html tables to pdf using WeasyPrint==0.42.2Ritzy
C
-2
   **@page {
            margin-top:21% !important; 
            @top-left{
            content: element(header);

            }

            @bottom-left {
            content: element(footer
 }
 div.header {

            position: running(header);

            }
            div.footer {

            position: running(footer);
            border-bottom: 2px solid black;


            }
           .pagenumber:before {
            content: counter(page);
            }
            .pagecount:before {
            content: counter(pages);
            }      
 <div class="footer" style="font-size:12pt; font-family: Arial; font-family: Arial;">
                <span>Page <span class="pagenumber"/> of <span class="pagecount"/></span>
            </div >**
Colunga answered 18/4, 2018 at 8:59 Comment(2)
since when does it work in browsers? en.wikipedia.org/wiki/… According to this table Margin boxes are not supported at allFuchs
You can make it work after embedding pagedjs :)Schafer

© 2022 - 2024 — McMap. All rights reserved.