Skip to content

Instantly share code, notes, and snippets.

@dholbert
Last active March 21, 2024 16:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dholbert/8ac4601598d90957d36b4a26575ea0d8 to your computer and use it in GitHub Desktop.
Save dholbert/8ac4601598d90957d36b4a26575ea0d8 to your computer and use it in GitHub Desktop.
Just print what I see on screen

When looking at bug reports in Firefox’s printing code, I occasionally see users requesting that we add a checkbox to our print dialog to “just print out the website exactly as I see it laid out on the screen”.

It turns out there are quite a few pitfalls buried in this proposed feature. Not-addressing those pitfalls would make the feature into a bit of a footgun; and it turns out that addressing the pitfalls would largely end up making the feature do what browsers already do for print layout.

Let’s explore this. Pretend you’re a browser developer who’s been tasked to implement this feature: a checkbox labeled “Print the website exactly as it looks in my browser” in the print dialog.

INITIAL VERSION: You add code to take a screenshot of the browser’s viewport (the viewport’s entire scrollable height), and then you draw that directly onto one or more printed pages, pixel-for-pixel.

It’s great! Users are intrigued by this checkbox and start using it, but pretty soon, you get a bunch of users reporting a bug that seems like something you should fix:

BUG: content runs off the paper. A user tried to print a website from a browser window that was a little bit wider than their printer’s paper; your code dutifully took a screenshot of the browser and tried to draw it to the paper, and it turned out to be too wide, and some of it ran off the edge and ended up missing.

  • PATCH: Let’s change things so that, if the on-screen layout is wider than a printed page, we downscale the screenshot when we draw it on the page. The content will be a little smaller, but it’ll fit nicely without getting cropped, and it’ll still be a screenshot of what the user saw.

A little while later, another bug arrives (and then another, etc.; I’ll stop doing these interludes)

BUG: text is too small to read. A user tried to print from a browser window that was much wider than a page (they’ve got a widescreen monitor and their browser is full-screen), and the downscaling that we’re doing to fit the paper (from the previous patch) ends up making the content too small to be readable. The user still wants to be able to use this checkbox, but they’re understandably frustrated that they need to manually resize their browser to some arbitrary size in order for that to Just Work nicely.

  • PATCH: let’s make the manual part automatic – let’s do a “behind-the-scenes” layout in a browser viewport that’s precisely the size of our printed page, and take a screenshot of that viewport to use for printing. Then it’ll be guaranteed to fit the page perfectly, and no downscaling will be needed. Hooray!

BUG: the checkbox doesn’t actually make the printout look like the browser layout that users see anymore. After the above patch (the “behind-the-scenes layout” at the size of a printed page), users notice that the printout often does not look like how it was laid out in their regular browser window. Line-wrapping is obviously different with the different viewport-size; and websites often have “responsive design” features that cause content to appear/disappear or shuffle around to completely different locations when laid out in a skinnier vs. wider viewport.

  • PATCH: None; nobody can really come up with a good idea for how to fully rescue this aspect of the checkbox without regressing the previous bugs, or risking overlapping/clipped content. You decide to live with this known limitation for now, and hope it doesn’t bother anyone too much.

BUG: my printer ran out of ink. A user tried to print a “dark mode” news article that had white text on a dark background, and it didn’t initially occur to them that this would literally mean they’d get ten nearly-solid-color pages. Since dark mode is getting more popular among tech folks, this feels like it might happen a lot.

  • PATCH: You change your code to start honoring the “Print backgrounds” checkbox. (This checkbox already exists and is off by default, to disable backgrounds by default for “regular” printing; but until now, you’ve been trying to preserve backgrounds as part of this new feature, in the interests of printing literally what the user sees on-screen in their browser window.)

BUG: my images are all split across pages. A user tried to print a document with a series of large images (maybe photos or shipping labels), and it just so happens that many of them end up being placed near the bottom of their page, which means they get split across a page-break, which isn’t great.

  • PATCH: add some logic to our page-splitting code, to add some spacing (not present in the original page) as-needed to push images (and similar elements) to the top of the next page when they’d otherwise be at risk of splitting across a page-break.

BUG: my news article only printed the first page. A user tried to print a long news article, with your checkbox checked (to print what they see on screen); but, they only got one page of output. As it turns out, this makes sense, because the website has CSS that sizes its outermost elements (<html>, <body>) to exactly fill the height of the browser’s viewport, and not be any taller than that. The actual article content is buried inside of some wrapper-element, and that element is styled to form its own scrollport for the article. So: when we do our our “behind-the-scenes” layout of the whole website (from one of our patches above, where we pretend the browser viewport is the exact size of a printed page), the site’s CSS ends up laying out the site to fit exactly on one printed page (our “viewport” in the behind-the-scenes layout) and the scrollable wrapper-element just clips its overflowing article content (just as it does on-screen, in fact -- except, it’s able to show a scrollbar there. Unfortunately we don’t yet have the technology for printing out a functional scrollbar onto paper).

  • PATCH: After lots of attempts to fix this by Just Finding The Scrollable Element With All The Content And Making It Span Multiple Pages, this turns out to be intractable to do robustly. However, it turns out you can fix this by just honoring @media print stylesheets, which are how websites provide print-specific CSS that let them avoid this sort of issue. This particular news website has a print stylesheet that makes the scrollable element not-scrollable and removes the height limitation on the outer elements, so that the article’s content-height contributes to the height of the document as-a-whole, which makes for printable multi-page output.

At this point we’ve managed to avoid a lot of the worst bugs that users ran across when checking this “Print the website exactly as it looks in my browser” checkbox, but in the process we’ve gone a good distance from actually doing what the checkbox says, and in fact we’ve gotten a good deal of the way to just reimplementing how browsers already do print layout.

Of course, we could have stopped at the first version with a literal pixel-for-pixel screenshot drawn to the paper. But that leaves this proposed feature as a prominently-featured footgun that potentially produces a worse and/or confusing result much of the time that it’s used, which is not great for most users.

Hence, this isn’t a feature that we’ve taken the invitation to implement, and I suspect we won’t any time soon; at least, not without a lot of careful thought to mitigate the footgun possibility and to usefully & clearly differentiate it from the default printing behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment