After Hours

Going further with the Paged Media Module and alternatives for creating paged media

Ryan Boudreaux goes over more examples of the Paged Media Module features, but also lists some of the options for creating paged media until browser support catches up with the new module.

A previous segment presented an "Introduction to the Paged Media Module in CSS3," describing the fundamentals of the Paged Media Module and CSS Generated Content for Paged Media Module, which is still a work in progress. This piece will dive deeper into some of the features of the module that are available now and others that will be available for use in future user agent releases.

Current support is limited to the @page size, :left, :right, and :first features in Chrome 7 and above, IE 8 and 9, and Opera 8 and above (more later on Dev Opera Labs), but as more of the features are supported by browsers, this will be a great way to set up content in fixed pages —saying goodbye to the ePUB file format and hello to streaming books online. For those who are interested in other options and commercial off-the-shelf (COTS) solutions to paged and printed media, I also offer several possibilities at the end of this post.

@page rule examples

I introduced the @page rule in the previous piece, as this is the typical first setup of the paged media, defining the basic settings such as page size, margins, left page, right page, and other features. Below, I give two examples of the @page rule code. The snippet in Example 1 sets the page size to A4, the margin to 25mm, adds the @top-center margin box with content sample, and the @bottom-center margin box with a page counter. Example 2 sets the @page size to 5.5in x 8.5in with a margin of 25px, a @top-center margin box with content header, and a @bottom-center margin box content page counter.

Example 1
@page {
size: A4;
margin: 25mm;
@top-center {
content: "Sample";
}
@bottom-center {
content: counter(page);
}
}
Example 2
@page {
       size: 5.5in 8.5in;
       margin: 25px;
}
@top-center {
       content: header;
}
@bottom-center {
       content: counter(page);
}

Margins

The margins can be set as displayed in the examples above, or can be set for each side individually, as shown in the code snippet below, where the top and bottom margins are set to 2cm, and the left and right margins are set to 3cm:

@page {
margin-top: 2cm;
margin-bottom: 2cm;
margin-left: 3cm;
margin-right: 3cm;
}

Margin Boxes

Margin boxes can be assigned to one or more of the 16 areas indicated on the page model, and are named for the specific location such as @top-left, @top-center, @bottom-left-corner, etc. The page model layout with main page area and margin boxes is displayed in Figure B below.

Page progression

The page progression for print layout is the direction in which printed pages of a document are sequenced when laid out side-to-side, whether they are printed in duplex form or not. The rules are different for horizontally-set English and Japanese language typesets, which typically progress from left to right; however, Arabic and vertically-set Japanese language typesets typically progress from right to left. To clearly force a document to begin printing on a left or right page, developers can insert a page break before the first generated box. You can specify the first page settings as well as left-side and right-side pages for printed formats with the @page: first, the @page: left and the @page: right settings; the content property can be used to string chapters and counters (more on these in a bit), as shown in the examples below:

@page :first {
@top-right { content: normal }
@top-left { content: normal }
}
@page :left {
margin-left: 23mm;
margin-right: 27mm;
@top-left {
content: string(chapter);
}
@bottom-left {
content: counter(page);
}
}
@page :right {
margin-left: 27mm;
margin-right: 23mm;
@top-right {
content: string(section);
}

Headers and page numbers

Textual content from headings in the body of the HTML can be displayed in page headers using the string-set property and chapters using the string() function; an example is shown in the code snippet below:

Example of chapter

@page {
       @top-left {
    content: string(chapter);
}
}
h1 {
  string-set: chapter content();
}

Counters are the method given by CSS to achieve numbering of paged media. Counters can be used to number list items, pages, footnotes, sections, and any other document content that needs to be numbered. Page number strings can be invoked in the content counter(page) property for generating page numbers as shown in the code snippet below:

@page {
       @bottom-center {
       content: "Page " counter(page);
       }
}

Other page numbering options include a total pages counter with the current page as in the form such as ‘Page 17 of 23', an example is shown in the code snippet below:

@page {
@bottom-center {
content: "Page " counter(page) " of " counter(pages);
}
}

Other options for paged media

There are many efforts that go beyond the limited browser support of the paged and print media specifications including Opera development labs; Google Code for converting HTML to PDF using WebKit; WeasyPrint, which uses HTML plus CSS exporting to PDF; and several COTS solutions such as Prince and Antenna House.

Dev Opera Labs

Dev Opera presents some fun with getUserMedia and it splits content up into native pages; the example below turns the contents of an entire web page into a paged experience

  @media -o-paged {
    html {
      height: 100%;
      overflow: -o-paged-x;
    }
  }

For more information about the @media -o-paged media type and the Opera Reader, check the Opera Software reader piece, Opera Reader: Paging the Web.

Google Code: Convert HTML to PDF using WebKit - wkhtmltopdf

The project is a simple shell utility that is used to convert html to PDF using the webkit-rendering engine, and QT. Features include converting web pages into PDF documents using webkit, adding headers and footers (static version only), adding TOC generation (static version only), a batch mode for conversions, and for Linux no longer requires an XServer to be running (however the X11 client libs must be installed). Bindings for PHP and Python are also available.

WeasyPrint

The open source HTML + CSS to PDF system found at weasyprint.org is written in Python, and is a visual rendering engine that takes HTML and CSS and exports it to PDF, using and supporting the web standards for printing. The code snippet below is an extract from their sample CSS21-print.css:

@page {
    margin: 3cm 2cm; padding-left: 1.5cm;
    @top-center {
        content: "Introduction to CSS 2.1";
        vertical-align: bottom; border-bottom: 0.5pt solid }
    @bottom-right {
        content: "Page " counter(page) " of " counter(pages) }
    @left-top {
        content: "W3C Recommendation";
        background: #005a9c; color: #fff; text-align: right;
        transform-origin: 100% 0; transform: rotate(-90deg) }}
body { text-align: justify }
h1 { -weasy-bookmark-level: none }

COTS Solutions

While the paged media efforts will eventually assist traditional publishing houses trying to keep up with the move from the print to digital format delivery model, it is also a great way for online outlets to offer their content in other media formats as well. If you want to forgo the do-it-yourself paged media solution and are looking for an immediate COTS product solution, several PDF publishing technologies in use today utilize the EPUB file format, and include PDF processors such as Prince and Antenna House; however, both come with a price tag ranging from as little as $495 for the Prince single user professional license, and up to a $7,000 fee per server license for the Antenna House XSL/CSS Formatter V6 product. The Apache Cocoon Project provides another system and format for publishing XML documents in HTML and PDF, using simple XSLT transforms. Another option, IBM Developer Works, describes a way to publish XML documents in HTML and PDF using the css2xslfo utility. And finally, dotEPUB, software from the cloud-based e-book maker, allows you to convert any webpage to an e-book format including EPUB and .mobi.

Prince XML also provides an extensive User Guide as a great resource and quick reference for CSS properties, CSS selectors, JavaScript, paged media, and their Paged Media User Guide includes notes on page size, page style, headers and footers, page selectors, and more.

About Ryan Boudreaux

Ryan has performed in a broad range of technology support roles for electric-generation utilities, including nuclear power plants, and for the telecommunications industry. He has worked in web development for the restaurant industry and the Federal g...

Editor's Picks

Free Newsletters, In your Inbox