Can we show an alternate image in print.css?

I would like to show an alternate image in print.css. That is, when they click on the browser’s print button, I want to swap out an image for a fuller picture for output.

I tried using background-image:url() !important in the print.css but that doesn’t work (I suppose it is standard not to print background images).

I know I can put the alternate image in html and do a display: hide for that page’s styles.css, then for the print.css display: block it and display: hide the original. The problem is that the page will load both images, and the alternate is a larger image and will slow down loading on mobile.

Is there some way to swap an alternate image when a browser’s Print button is used?

It could possibly be done using the <picture> element. Though I have not tried it for print, only differing screen sizes.

Try something like this

<html lang="en">
<title>Background Image Print Test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style type="text/css">
@media print {
  #test:after {
    content: url("./images/horizon-tilt.jpg");
<h1>Background Image Print Test</h1>
  <div id="test">

Thank you! This is genius! Worked great after I added to the stylesheet:

    #test {
        display: block;
        width: 100%;

Are you sure its working?

In my tests (in Chrome) the image is not loaded the first time you try and print the page. If you try a second time then the image appears.

The image seems to need to be in cache before the print is selected. The only way I can see that that will happen is by loading it by default in the main stylesheet and hiding it offscreen and then just revealing it in the print stylesheet. This of course means the image is loaded when it may never be needed.

Are you getting different results?

Works immediately in IE and FF. Now that I try it in Chrome, I can see it does not appear immediately.


That’s what I get for not thoroughly testing.

I tried moving it out into a CSS file both as a media=“print” and a file with @media but still no joy.

I’m thinking if this approach is to be of any value for counting user “print” actions, some server-side stuff will need to be done.
And the success of that depends on when exactly the assets do get called in.

Dev tools shows the status as “pending” the anonymous function “window.print()”

So it looks like the more reliable way would be using JavaScript to test for
onbeforeprint / window.matchMedia('print')

Since I have already implemented this on the few pages on hand, I will not bother with counting the use.

I thought I would give this a try using the media attribute in the picture element. But it does not seem to work.

                <source media="screen" srcset="">
                <source media="print" srcset="">
                <img src="" alt="an image">

Not sure if I got something wrong in the syntax, or it just doesn’t work and browsers are lazy and print what is there already, rather than re-loading for the preview.
I thought I may be on the right track with this, but no.

Nice try Sam. Good thinking. Shame it didn’t work…

If you convert the image to base64 then it seems to work ok.

PaulOB: I clicked on your “seems to work” link and did a print preview. It did not show any image in FF.

SamA74: you mentioned this idea earlier. It did not work for me either. Thanks!

It’s working in Chrome, ie11 and edge but Firefox has the same problem as before in that it only prints on the second time.

Thanks for clearing that up!

This small change solves the issue for all three major browsers:
content: url(images/top-down.jpg);

It no longer requires printing twice in Chrome. Here’s how I use it (I want the cropped top-down.350.jpg on the web page to be replaced with top-down.jpg in print):


    <section id="contentleft">
            <a href="images/top-down.jpg">
                <img src="images/top-down.350.jpg" alt="top view">
        <div id="printchassis"></div>


    #contentleft {
        display: none;

    #printchassis:after {
        content: url(images/top-down.jpg);

Accidentally found on this page:

What small change?

That looks the same as we already discussed unless I’m missing the obvious :slight_smile:

Do you have a demo?

1 Like

content: url("./images/horizon-tilt.jpg");

content: url(images/horizon-tilt.jpg);

Maybe eliminating "./ was the difference?


No that’s not working I’m afraid and the print image only shows the second time around as already demonstrated in my previous example. Changing the url path is not going to make a difference to this issue (unless of course you point to the wrong place).

You need to clear your cache to test.

Also why are you linking to 2 print stylesheet files that are almost the same?

Note that because you have media = print in the link tag then there’s no point specifying a media in the actual css file.