Paged.JS and CSS Flex / Grid

Paged.JS is a marvel. It’s a Javascript library which helps paginate HTML content, making it suitable for print output. It implements a lot of the CSS Paged Media specifications – so I guess you can think of it as a polyfill. I’ve combined it with Puppeteer to transform a variety of HTML documents into PDFs, complete with repeating headers, footers, footnotes, etc.

It’s amazing, but imperfect. I’ve run into a few issues in the current version (v0.2.0 at the time of writing). My HTML documents make extensive use of CSS flex and grid for layout. For the most part this works fine with Paged.JS, except at the borders between pages. For example, I can use break-inside: avoid to avoid page breaks from happening inside an element:

@media print {
  .block {
    break-inside: avoid;
  }
}

However, if that element happens to be either a flex parent (it has display: flex;) or a flex item (it’s a direct child of a flex parent), the break-inside property is either ignored, or causes other “interesting” issues. Improvements are on the roadmap, but in the meantime we need a workaround. It’s not ideal, but the most reliable way I’ve found is to fall back to older layout techniques, like block, inline-block or float:

@media print {
  .block {
    display: block;
    break-inside: avoid;
  }
}

They’re obviously not quite as flexible, but they work!

It’d be really nice if the various browser engines out there implemented more of the Paged Media specifications natively. As much as I love Paged.JS, I’d love to be able to remove it. Maybe one day…