Printer Friendly CSS

So there is a couple of us at SP who have been playing with a print media css queries to try and make Discourse more “printer friendly”, so far we’ve come up with

@media print {
/* remove items N/A for print
** visual clutter etc. */
  .avatar,
  .topic-avatar,
  header,
  div.ember-view.topic-above-post-stream-outlet.topic-above-post-stream,
  div.ember-view.topic-map,
  section.ember-view.post-menu-area.clearfix,
  div#topic-footer-buttons,
  div#suggested-topics,
  div#progress-topic-wrapper,
  #topic-progress-wrapper,
  div.nums,
  ._flyout,
  .ember-view.btn,
  #topic-progress,
  .quote-controls,
  #topic-closing-info,
  div.lazyYT,
  .post-info,
  .saving-text,
  .draft-text,
  #discourse-modal,
  div.read-state,
  div.read-state.read,
  .edit-topic,
  a.reply-to-tab,
  a.reply-new,
  div.has-pending-posts,
  div.time-gap {
    display: none !important;
  }
/* bottom border to help separate posts */
  div.row {
    border-bottom: 1px solid #888;
    margin-bottom: -1px;
  }
  .cooked pre code { max-height: none; }
  #main-outlet { padding: 0 !important; }
  html,body { min-width: 0; height: auto; }
  .lightbox-wrapper img { max-width: 500px !important; height: auto !important; }
  .topic-body { width: auto; margin: 0; padding: 0; float: none; }
  .topic-post article.boxed .select-posts { width: auto; left: auto; right: 0; }
  .gap { width: auto; }
  .gutter { padding: 0; }
/* restyle div#topic-title */
  #topic-title {
    margin: 0;
    padding: 0;
  }
  #topic-title div div h1 {
    margin: 0 1em 0 0;
    padding: 0;
    float: left;
    font-weight: normal;
    font-size: normal;
  }
/* hide OP Solved plugin stuff */
  div.ember-view.topic-after-cooked-outlet.solved-panel {
    display: none;
  }
/* localhost  - MOOT for production */
  div.ember-view.topic-category-outlet.show-topic-category-location,
  div.alert.alert-info.alert-emails-disabled,
  div.profiler-results.profiler-left.profiler-no-controls {
    display: none;
  }
}

Is this something the Discourse Team would accept in a PR on common.scss? (or desktop.scss)

8 Likes

Thanks! Implemented with some tweaks. Never occurred to me I could clean up the print version…

Mind posting your tweaks here, because if a PR is going to be accepted, I’ll definitely take it into consideration when I submit the PR.

If they were theme specific, no need to mention them here. :wink:

1 Like

Sure I think this would be great! Screenshots of the print preview GUI with it in place?

1 Like

Fake posts by fake accounts on localhost

screen view

print preview

1 Like

Sure. I’ve stripped out my theme specific tweaks, and what’s left are overall improvements.

Full code:

@media print {
/* remove items N/A for print
** visual clutter etc. */
  .avatar,
  .topic-avatar,
  .badge-category,
  .badge-category-bg,
  .badge-notification.clicks,
  header,
  div.ember-view.topic-above-post-stream-outlet.topic-above-post-stream,
  div.ember-view.topic-map,
  section.ember-view.post-menu-area.clearfix,
  div#topic-footer-buttons,
  div#suggested-topics,
  div#progress-topic-wrapper,
  #topic-progress-wrapper,
  div.nums,
  ._flyout,
  .ember-view.btn,
  #topic-progress,
  .quote-controls,
  #topic-closing-info,
  div.lazyYT,
  .post-info.edits,
  .post-action,
  .saving-text,
  .draft-text,
  #discourse-modal,
  div.read-state,
  div.read-state.read,
  .edit-topic,
  a.reply-to-tab,
  a.reply-new,
  div.has-pending-posts,
  div.time-gap,
  #bottom,
  #footer {
    display: none !important;
  }
  
/* bottom border to help separate posts */
  div.row {
    border-top: 1px solid #AAA;
  //  margin-bottom: -1px;
  }
  .cooked pre code { max-height: none; }
  #main-outlet { padding: 0 !important; }
  html,body { min-width: 0; height: auto; }
  .lightbox-wrapper img { max-width: 500px !important; height: auto !important; }
  .topic-body { width: auto; margin: 0; padding: 0; float: none; }
  .topic-post article.boxed .select-posts { width: auto; left: auto; right: 0; }
  .gap { width: auto; }
  .gutter { padding: 0; }
  
/* restyle div#topic-title */
  
  #topic-title {
    margin: 0;
    padding: 0;
  }
  #topic-title div div h1 {
    margin: 2.5em 0 0 0;
    padding: 0;
    float: left;
    font-weight: normal;
    font-size: normal;
  }
  
  a, a:visited {
      color:#DDD;
      font-weight:bold;
  }
  
/* hide OP Solved plugin stuff */
  div.ember-view.topic-after-cooked-outlet.solved-panel {
    display: none;
  }
/* localhost  - MOOT for production */
 // div.ember-view.topic-category-outlet.show-topic-category-location,
 // div.alert.alert-info.alert-emails-disabled,
 // div.profiler-results.profiler-left.profiler-no-controls {
 //    display: none;
 // }
}

The fastest way to see the changes is on a text comparison site like http://text-compare.com/.

###Display:none

  .badge-category,
  .badge-category-bg,
  .badge-notification.clicks,

Got rid of the category, its color bar, and the link click annotations. Once it’s ready for print, none of these are relevant.

 .post-info.edits,
 .post-action,

Made this more specific; hides the number of edits but brings the date back. I think dates on posts are very relevant even on printouts. Post-action hides the “three people liked this”.

#bottom,
#footer

I know, footer and bottom sections could be printed, but it tends to add an extra page while printing. I hate that. This is my revenge for all those wasted sheets of paper over the years.

###Border tweaks

/* bottom border to help separate posts */ 
div.row { 
border-top: 1px solid #AAA; 
// margin-bottom: -1px; 
} 

I like the border thicker and darker, and the bottom-most one is wasted. So, I put it at the top instead, and removed the bottom margin to make it double thick. Lightened it up a bit. This is just my preference.

#topic-title div div h1 {
    margin: 2.5em 0 0 0;
    padding: 0;
    float: left;
    font-weight: normal;
    font-size: normal;
  }

Added some top margin for the title, looks better and prevents clashing with the browser date/title headers. Removed right margin, not sure what it was for (had no effect in my testing).

###Link style

a, a:visited {
      color:#DDD;
      font-weight:bold;
  }

Out of respect for laser printers, I restyled the links a bit. You can’t see blue in monochrome. Blue is useless on paper anyways, just a waste of color ink. Bold font yet light grey makes it easy to tell where a link was, without being visually distracting. Works equally well for color and B&W printers.

I also commented out the localhost bits… since it said moot for production and I didn’t know what the intent was.

2 Likes

Easiest way to see the print preview is to go on a thread and hit Ctrl-P. Here’s one with lots of pictures, likes, post edits, videos - the works.

Here’s a few screenshots:



One thing I just noticed, it will only print out the first few posts - presumably however many DIscourse had loaded up. At the end of a thread it will print the last few posts.

How do you propose to print only a certain post, range of posts, or the whole shebang?

2 Likes

For a single Post, isn’t that what “Print Selection” is for? As for the whole shebang, that is impossible currently.

Hmm, interesting. First off it’s a bit tricky to select a single post, but you’re right it can be done, and “Print selection” will print whatever you selected. If you want any “extra” stuff besides the post text, you’d better select it too.

It seems once you choose “print selection”, it disregards the media query and just uses the default styling… avatars come back, reply buttons, etc.

I guess the question is, what is our target user trying to do? If she can’t print a long thread entirely, and printing a single or multiple specific posts depends on her text selection skill (and apparently discards the media query); this seems a bit useless.

If someone only wants the first few or last few posts, or a loose selection in the middle, they can position the browser on the middle of what they want and it should print OK. Short threads should print in their entirety as well.

The goal, to give Discourse printer friendly CSS. If time comes where a feature is added to put all posts on a single page for printing, at least the CSS exists. For short topics, this will work great as is.

But ultimately, we have a few users who want a print friendly output, and this will suit them well enough for now.

PR submitted (images attached to GitHub PR)
https://github.com/discourse/discourse/pull/3595

@ky_metro, I incorporated all of your adjustments, I think they worked out well.

8 Likes

Actually, this is not entirely true. Here’s how to do it… involves disabling javascript in your browser before loading the topic. Produces a very passable view suitable for printing or saving as PDF.

I am extremely excited to see this pull request and discussion happening - print view is one of the most asked for features for my community… we have alot of folks in “internet remote” locations who would love to download and read topics offline. Also we use discourse for collaboratively creating documentation that we’d like to be able to share beyond discourse.

What I would really like actually is a link on the sharing link on the popup that then downloads as a PDF the whole shebang (when sharing link at bottom is used) or just an individual post (when the post timestamp is used). That can then be shared or printed out.

Well, yes, if you wish to take the time to do it page by page and then combine them all. My point was, there isn’t a “all posts in one output” availability to Discourse.

Not sure what you mean… it’s a quick process to turn off javascript, open the page, save as PDF. It saves the whole shebang.

Here’s an example:

But it isn’t the “whole enchilada”. It’s paginated. i.e. AFAIK you can’t load a > 20 posts topic all in 1 go.

Ah. Gotcha. That hasn’t been an issue in our smaller community, and in any case we’ve been mostly interested in sharing topics we’ve been collaboratively developing as documentation.

So my community would be interested enough in this to contribute $$$ to have it developed and contributed to discourse, perhaps as a plugin if that’s possible or as core if it’s so desired. Happy to take proposals.

The whole enchilada is going to be tricky, it is going to have to have some hard limit as well, printing a 20000 post topic for example is going to lead to much pain

2 Likes

I’m sure it could be done. My main thoughts were “something is better than nothing” and the New England Yankee in me not wanting to use twice as many pages to print content and a mess of action buttons and link text that meant nothing on a printed page. Not that paper and ink are all that expensive, just the same, why use 8 sheets when 4 will do?

* to clarify, I personally do not print topics, but others do. More of a “in their shoes” thing.

Maybe save to pdf (of topics over 20 pages and therefore requiring pagination) could be handled like a backup? e.g. start creating the PDF as a background task and send me a PM with the link to download?

Or perhaps limit the save to PDF to post, all topics if under 20 topics, or to topic summary which would also be within the 20 topic length.

Edit: Would the inclusion of this PR make Discourse more Pocket-friendly? I’ll be sure to test that for you as soon as this is live on Meta.

On a different note, for those more edge case scenarios, I’m sure there’s all sorts of wizardry to explore on the client-side alone. Just thought of this thread when I noticed this on HN today:

Pretty Print Gmail - Chrome Extension