8

Background: I have a PHP script that generates a long HTML/CSS document that gets converted to a PDF with WkHtmlToPdf.

At one point in the document, we enter a dynamic area with a variable number of entries, some of which include large images. I want to redraw a header on every page.

Point of clarification: This is a repeated header in the print view of a section of a webpage, not just a header for the entire page.

How I want to do that is via CSS. For example (pseudocode):

    #some_region:pagebreak {
      background-color: #fcc;
      border-color: #000;
      border-style: solid;
      border-width: 0 0 1px 0;
      content: "Our Header Here";
    }

Of course, this fictitious CSS3 selector does not exist!

Are there any clever CSS hacks that can be used to display an element after any page-breaks within a certain container?

To illustrate: https://scott.arciszewski.me/public/23277702.php

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
  • Are you looking to paginate some specific results? Bootstrap (freely available) has a paginate component and they have a download builder set up to just give you specific components. – Pseudonym Apr 24 '14 at 19:19
  • This is going to be printed. Bootstrap's paginate is suited for web pages, not printed documents. – Scott Arciszewski Apr 24 '14 at 19:23
  • Ah, you're right my mistake then – Pseudonym Apr 24 '14 at 19:27
  • @Scott I wonder **how** you achieve the page-breaks at all? Because if there is "a variable element" somewhere on the page, all subsequent page-breaks may change. Or do you simply mean, that you want a header at the top of each page (with automatic page-breaks)? – Netsurfer Apr 27 '14 at 14:43
  • "Or do you simply mean, that you want a header at the top of each page (with automatic page-breaks)?" Yes. But only for a subset of the total document. – Scott Arciszewski Apr 28 '14 at 13:23
  • Does this answer your question? [How to use HTML to print header and footer on every printed page of a document?](https://stackoverflow.com/questions/1360869/how-to-use-html-to-print-header-and-footer-on-every-printed-page-of-a-document) – Chris Moschini Oct 29 '20 at 21:32

3 Answers3

11

What about a position: fixed; header in @media print? That would force a header on each printed page. Something like:

    @media screen {
        .print-header {
            display: none;
        }
    }

    @media print {
        .print-header {
            position: fixed;
            ...
        }
    }
JimmyRare
  • 3,958
  • 2
  • 20
  • 23
  • Will that allow me to add a header to only a certain region of a webpage? – Scott Arciszewski Apr 27 '14 at 03:42
  • At the top of page 3, 4, 5, and 6 of a 7 page document, for example. – Scott Arciszewski Apr 28 '14 at 13:20
  • May I ask what would trigger a header if it is not content or a new page? – JimmyRare Apr 28 '14 at 16:41
  • @Scott this is in deed the correct answer. The `position` attribute does that job. You can use `fixed` for all pages or `absolute` for single pages. Just add the header, or a `:after` element right after each page break and you should have your wanted result. BTW, this is broken in Webkit (https://bugs.webkit.org/show_bug.cgi?id=100075) you'll need to use FireFox for now. – codingjoe Apr 28 '14 at 16:51
  • The essence of my problem is I do not have a way to detect when a page break has occurred between list items. – Scott Arciszewski Apr 28 '14 at 17:33
0

Could you achieve it with the --header and --footer arguments of wkhtmltopdf? There is a help section at

$ wkhtmltopdf -H

Edit

As could be seen in the comment section not fully an answer to this question, but might still be valuable to users searching for related issues:

This blog post shows how to render headers or footers on arbitrary page(s) with wkhtmltopdf: http://biostall.com/wkhtmltopdf-add-header-footer-to-only-first-last-page

sthzg
  • 5,514
  • 2
  • 29
  • 50
  • That applies it to the whole document. I'm looking for a repeating header within a subsection of the document, with just CSS (so it can be reproduced when testing it in a webkit compatible browser) – Scott Arciszewski Apr 24 '14 at 19:17
  • 1
    Does this section always start at a new page or can it start just in-between? I just thought about a y-repeating dynamically generated background-image with the height of page-height, that could span the section container. But I am quite sure there is a more elegant solution to this. :) – sthzg Apr 24 '14 at 19:35
  • Its beginning offset is slightly variable: The relevant container is the most dynamic element in the document, but not the first or only one. However, for many peoples' use cases, that is a sufficient hack. :D – Scott Arciszewski Apr 24 '14 at 19:36
  • Okay, so that means this section could possibly start somewhere mid-page. The css-headers should then print after each consecutive page-break until all values of that dynamic section are printend. Afterwards other content could follow that like the upper content does not need any headers? – sthzg Apr 24 '14 at 19:46
  • There is of course the option with javascript. Not pure CSS, but at least wkhtmltopdf handles it quite well and it solves the issue that it has to work in browser too. I am curious if there are other ways – but since it has to look the same way in the browser I'm wondering how. Outside of print stylesheets the viewport does not know about the pagebreaks. – sthzg Apr 24 '14 at 20:25
  • 1
    I may need to consider poking the W3C and making this a feature request for either the HTML5 or CSS3 standards. Won't help for the short term, however. – Scott Arciszewski Apr 24 '14 at 20:27
  • 1
    Again – not in browser, but this looks promising for the pdf at least: http://biostall.com/wkhtmltopdf-add-header-footer-to-only-first-last-page – sthzg Apr 24 '14 at 20:48
0

If I'm understanding correctly, if each "container" after a page-break may be given a class name, you may simply use pseudo-elements:

Example: JS Fiddle

.container {
  position: relative;
  background: #eee;
  padding: 35px 5px 5px;
  margin-bottom: 10px;
}
.container:before {
  position: absolute;
  top:0;
  left:0;
  padding: 5px;
  background: #aaa;
  content:"Here's the header content!";
}
Todd
  • 185
  • 10
  • It doesn't need to appear before each individual element. Imagine a list of 900 items of variable length. After a certain point, a page break occurs. What I want to accomplish is, instead of just continuing on to the next item, draw the header again first. – Scott Arciszewski Apr 24 '14 at 19:57
  • Hmm, if there is some kind of selector atop that new page break, just swap that for the above `.container` selector. – Todd Apr 24 '14 at 20:06
  • Well, how do we know when a page break has occurred with just CSS? That's the conundrum I'm running into. – Scott Arciszewski Apr 24 '14 at 20:07
  • This seems difficult to visualize w/o an example. – Todd Apr 24 '14 at 20:09
  • Not really, @Scott. I don't believe there's a way to do this with just CSS. If you could dictate where that page break would be, you could use the `page-break` properties: http://css-tricks.com/almanac/properties/p/page-break/ – Todd Apr 24 '14 at 20:33