Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS and HTML print setup for multi-page documents with running header and footer

Tags:

html

css

printing

I am having nightmares figuring out how to properly set CSS and HTML layout for printing documents in our web-app. We have different documents that come into the system (order, invoice, delivery notes, ...). The documents consist of:

  • static header (company logo, contact info)
  • body
    • customer data (shipping, billing address)
    • items table (table with several rows, which can spread trough several pages)
  • static footer (disclaimer)

What I want is following print functionality:

  • I want static header and footer to be printer on each page if the body spreads trough several pages
  • The items table to have a table header printed in every page if it spreads in more pages

Currently my HTML layout is like this:

<!-- STATIC HEADER -->
<div id="pageHeader">
    <table class="table">
        <tr>
            <td>Static header content here</td>
        </tr>
    </table>
</div>

<!-- DOCUMENT CONTENT -->
<div id="pageBody">

    <!-- Customer data -->
    <table class="table">
        <tr>
            <td>Customer data here</td>
        </tr>
    </table>

    <!-- Items table -->
    <table class="table table-condensed table-print">
        <thead style="display:table-header-group;">
            <tr>
                <th>Table header here</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Rows here</td>
            </tr>
        </tbody>
    </table>

</div>

<!-- STATIC FOOTER -->
<div id="pageFooter">
    <table class="table">
        <tr>
            <td>Static footer content here</td>
        </tr>
    </table>
</div>

I was reading about running headers and footers following answer on this question but I don't get the desired results. Currently my CSS is set like this:

#pageHeader, #pageFooter { display: none; }

@media print {
    #pageHeader { display: block; position: running(pageHeader); width: 100%; }
    #pageFooter { display: block; position: running(pageFooter); width: 100%; }
}

@page {
    @top-center {
        content: element(pageHeader);
    }

    @bottom-center {
        content: element(pageFooter);
    }
}

Firefox gives me completely strange results. It first prints a blank page, then the second page is ok if it's a single page document, if it's a multi-page document then it only prints first page, other pages are ignored.

Google Chrome is slightly better. It prints all pages but it wont print static header and footer on every page. Header is printed only on first page, while footer only on last page.

Also the other problem is that the main table that can spread trough several pages does not print table header in every page if the table spreads trough multiple pages. I thought that display:table-header-group; on <thead> supposed to do that?

Is this just impossible to achieve or am I doing something completely wrong? If you can give me any advice or strategy on how to handle this I will be very happy. Since this app is running in controlled environment I can focus on one or two browsers (Chrome and Firefox would be great). If it works in both is bonus!

like image 642
Primoz Rome Avatar asked May 27 '13 07:05

Primoz Rome


1 Answers

Focusing the same issue I did some research. Here my results:

The display:table-header-group; doesn't work in chromium/chrome/webkit/.. because its not implemented. There is an open issue since 4 years. https://code.google.com/p/chromium/issues/detail?id=24826

You wanted to use @top-center and @bottom-center. This would be a great think. It's declared here h ttp://www.w3.org/TR/2013/NOTE-css-print-20130314/#at-rules but refering to http://en.wikipedia.org/wiki/Comparison_of_layout_engines_(Cascading_Style_Sheets)#Grammar_and_rules it is not implemented by any layout engine. I don't know why its mentioned here http://alistapart.com/article/boom. Anyone any idea?

The reason why you get your header on the first page and the footer on the last one is quite simple: just cut out the @page section and you see: @media print { ... display:block ... If you declare you footer on top, it does not work.

like image 129
Lukas Bernhard Avatar answered Nov 15 '22 08:11

Lukas Bernhard