How to make online pages that also print nicely as PDF?

I need to print workbooks containing some of the articles I’ve written on my minimal-mistakes derived site. Sometimes Chrome converts them into well formatted PDFs. Other times it does things like ignore .align-left and puts page breaks in places I don’t prefer. Also some of the articles include YouTube videos which don’t make sense to include in the printed versions.

It seems like I might be able to use “@media print” for print-specific behavior. Am I on the right track with this?

Yes you’re on the right track. Here’s a pretty good resource on cleaning up your print stylesheets.
And if you’re looking to modify MM’s print styles they’re in https://github.com/mmistakes/minimal-mistakes/blob/master/_sass/minimal-mistakes/_print.scss

1 Like

I noticed that _print.scss contained this:

 .no-print {
    display: none;
  }

So in my .md file I was able to keep the video out of the printed version of the page by wrapping it thus:
56%20PM

Again, I don’t know if this is the best way. Please bear with me as I learn.

Since _print.scss contains this:

  .page-break-after {
    page-break-after: always;
  }

I was able to force a page break in the printed output like this:
image

When printing PDFs from Chrome on macOS Catalina (10.15.1), pages containing a mix of Japanese and alphanumeric text are garbled as follows.


Interestingly, my wife’s Mac with Mojave did not have this problem. And I only had the problem with Chrome. But unfortunately Safari and Firefox both have even worse problems with printing from my site.

In my Minimal-Mistakes derived theme, I was able to fix the garbled text by removing BlinkMacSystemFont from _sass/minimal-mistakes/_variables.scss
image

resulting in:

$sans-serif: -apple-system, "Roboto", "Segoe UI",
  "Helvetica Neue", "Lucida Grande", Arial, sans-serif !default;

I am currently having a problem keeping headers grouped with paragraphs. _print.scss has settings that are supposed to discourage page breaks after headers, but I still get stuff like this H3 by itself at the bottom of the page, separated from the paragraph it describes (unless I force a page break in the .md file):

image

image

I believe that “page-break-after: avoid” from _print.scss is the setting that it supposed to keep the header with the following paragraph. From what I’ve read, this doesn’t work inside floating elements. I’m thinking I might be inheriting float from elsewhere in the theme.

Has anyone gotten this to work before?

I was wrong to think Chrome supported page-break-after: avoid. I couldn’t get Chrome to honor it even experimenting with a simple text file. (Safari and Firefox are even worse.) But I found a workaround online. I’ve added this to my _print.scss, and I’m no longer getting headers at the bottoms of pages.

// Workaround from https://stackoverflow.com/questions/9238868/how-do-i-avoid-a-page-break-immediately-after-a-heading
  h1::after, h2::after, h3::after, h4::after, h5::after, h6::after {
      content: "";
      display: block;
      height: 100px;
      margin-bottom: -100px;
  }

AMENDMENT TO ABOVE: I was still getting undesired page breaks after (rather than before) H2 headers. It was weird that I was getting them with H2 and not H3. They went away when I commented out these lines from _page.scss. I guess this means my H2 headers won’t have horizontal lines under them, but I didn’t actually care for that effect anyway.

image

You can use Prince to do this for very large sites:

https://www.princexml.com/

Also a bit of a docs perspective here:

https://idratherbewriting.com/documentation-theme-jekyll/#generating-pdf

1 Like

Thank you @moxiegirl. I got as far as installing Prince on my Mac, but haven’t taken further steps on that yet.

Here’s an easy change that made a big difference in making the printed output look like it was meant to be printed, rather than a printed web page. I changed font-family to $serif. I would suggest this as the default for printed body text to @mmistakes and other theme designers. Here’s what’s in my _print.scss now:

body {
    margin: 0 auto;
    background: #fff !important;
    color: #000 !important;
    font-family: $serif;  // I sought the serif. 
    font-size: 0.85rem;
    line-height: 1.5;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }

Print stylesheets are a wholly different beast than CSS for screen. There are a number of resources that might help, and the best and most complete is this one from Smashing Magazine:

Browser support for some of these print media rules is spotty at best. If you really, really need to control the way that browsers print your pages I suggest that you actually design a PDF for print specifically with your content. It’ll be a pain to update content on the site and in the PDF, but you won’t be messing with CSS print rules that are at best going to effect 2 out of the 3 major browsers per rule, resulting in inconsistencies from one browser to another.

1 Like

Getting Prince working on my Mac took a few extra steps to get around OS/X’s security features. As of Dec 2 2019 these weren’t properly documented, except on their user forum. Prince seems to work great though! Without the unpredictable behavior I was getting from web browsers! Combined with the changes I’ve already made to the Minimal-Mistakes stylesheets, I’m pleased that I won’t have to maintain separate web versions and print versions of the same content.

To convert to PDF and view it immediately in Preview while running jekyll --serve, I just type

prince http://localhost:4000/articles/ -o out.pdf && open out.pdf