97

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.

Donvino
  • 2,407
  • 3
  • 25
  • 34
  • possible duplicate of [Page numbers with CSS/HTML](http://stackoverflow.com/questions/6109893/page-numbers-with-css-html) – James Donnelly Jan 24 '14 at 14:12
  • @James Donnelly Well the questions are simmilar, but I have an answer here for my question, as I did it. – Donvino Jan 25 '14 at 06:37
  • Try this: [How to number print pages?](http://stackoverflow.com/a/43768942/6557304) – Leon Freire May 04 '17 at 13:31
  • currently, manually implementing something like Rul seems to do in this question https://stackoverflow.com/questions/16297619 seems to be the only feasible way.... – phil294 Dec 02 '17 at 00:57

10 Answers10

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.

SaschaM78
  • 4,376
  • 4
  • 33
  • 42
Donvino
  • 2,407
  • 3
  • 25
  • 34
  • @donvin this does not seem to work in IE11. The counter is never incremented. – philk Nov 01 '15 at 01:06
  • @philk Well, I didn't try IE11, but if you wiil find the way to do it in IE11, you could write an answer here. – Donvino Nov 02 '15 at 09:10
  • `counter-increment` should work since IE8 : https://developer.mozilla.org/en/docs/Web/CSS/counter-increment – Raptor May 23 '16 at 04:30
  • 75
    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. – Sonal Nov 30 '16 at 06:27
  • 16
    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. – Furbeenator Nov 30 '16 at 23:49
  • 13
    I suspect it never really increments because while it is shown on every page it's still one and the same element. – Ytrog Dec 05 '16 at 11:10
  • 2
    It seems that support for CSS Paged Media is starting to appear in some major browsers. https://caniuse.com/#feat=css-paged-media – Dylan Kinnett May 29 '18 at 17:08
  • 6
    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. – Kansha Dec 21 '18 at 00:55
  • this code does increment for me but is showing only in the last page of pdf like page 3 only in the last 3rd page – Juke Sep 23 '19 at 18:48
  • 1
    need add ``` body { counter-reset: page; } ``` – Chaos Fractal May 17 '20 at 16:54
  • 2
    None of the above solutions worked for me on Chrome. – Don Dilanga May 28 '20 at 14:04
  • 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 `
    ` and then after each section you could add a `
    ` and the class would contain `content: "Page " counter(page);`.
    – Leccho Oct 15 '20 at 15:06
39

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!

ˈvɔlə
  • 9,204
  • 10
  • 63
  • 89
  • 3
    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 :( – Ed the Coder Jul 09 '20 at 14:14
  • 2
    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! – WtFudgE Aug 23 '20 at 03:16
  • 1
    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. – Ganondorfz Dec 08 '20 at 00:27
  • @Ganondorfz Maybe you can try not to include pagedjs for regular browser-viewing? – ˈvɔlə Dec 10 '20 at 14:27
  • 4
    @Ganondorfz 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://stackoverflow.com/a/70054545/15273968 – the Hutt Nov 21 '21 at 12:47
21

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.top = "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>
madz
  • 168
  • 2
  • 11
littlejoe
  • 269
  • 2
  • 6
7

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/

Krish R
  • 22,583
  • 7
  • 50
  • 59
  • 43
    This is no longer supported by major browsers :( – philk Nov 01 '15 at 01:07
  • @Krish R, Seems you can help me. Look at this : http://stackoverflow.com/questions/43950603/how-can-i-not-display-page-number-1-in-pdf-hmtl-css – samuel toh May 13 '17 at 08:03
  • 4
    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 someone – contmp Sep 15 '17 at 01:44
  • 3
    This works for me using WeasyPrint (PDF generation tool). – damd Mar 13 '19 at 09:26
  • 6
    As of 2019, this _still_ does not work in CSS3. _This is not a solution!_ – Andrew Gray Jul 30 '19 at 18:45
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

Tongi
  • 127
  • 1
  • 1
  • for newest version of chrome, page number is always `0` even in the print screen. – Mar Tin Apr 06 '22 at 08:50
  • 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. – Ted Cohen Jul 03 '22 at 03:28
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.

Doodled
  • 186
  • 2
  • 11
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
clemoun
  • 298
  • 3
  • 14
  • `` since no one can seem to ever mention the url – toddmo Sep 27 '22 at 12:24
  • 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 https://pagedjs.org/documentation/2-getting-started-with-paged.js/ – clemoun Sep 28 '22 at 13:40
  • 1
    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. – toddmo Sep 28 '22 at 16:04
-1

This is what you want:

@page {
   @bottom-right {
    content: counter(page) " of " counter(pages);
   }
}
SaturnsEye
  • 6,297
  • 10
  • 46
  • 62
-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);
    }
}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
adorek
  • 9
  • 4
-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 >**
  • 2
    since when does it work in browsers? https://en.wikipedia.org/wiki/Comparison_of_browser_engines_(CSS_support)#Grammar_and_rules According to this table `Margin boxes` are not supported at all – user3568719 Jun 29 '18 at 18:42
  • You can make it work after embedding [pagedjs](https://www.pagedjs.org/) :) – ˈvɔlə Mar 25 '20 at 21:27