156

This question was asked before but the solution is not applicable in my case. I want to make sure certain background images are printed because they are integral to the page. (They are not images directly in the page because there are several of them being used as CSS sprites.)

Another solution on that same question suggests using list-style-image, which only works if you have a different image for every icon, no CSS sprites possible.

Aside from creating a separate page with the icons inline, is there another solution?

Community
  • 1
  • 1
DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290

13 Answers13

270

With Chrome and Safari you can add the CSS style -webkit-print-color-adjust: exact; to the element to force print the background color and/or image

rybl
  • 1,609
  • 3
  • 14
  • 22
Marco Bettiolo
  • 5,071
  • 6
  • 30
  • 35
  • 1
    @MuneemHabib It does not work in IE, actually, the only supported browser is Chrome: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust – Marco Bettiolo Jun 30 '15 at 13:07
  • that did the trick for chrome ... luckily in this case i only needed to support wekkit ... – Davy Aug 26 '15 at 09:45
  • 2
    @DisgruntledGoat should update this to be the correct answer as it quickly solved my problem (my project at work only focuses on Chrome). It obviously doesn't work for all browsers but it should be known, up front, regardless. – HaulinOats Mar 29 '16 at 19:36
  • 3
    @Brett84c: I disagree since it is a one browser only solution. – Kukeltje Feb 11 '20 at 17:41
  • Use ".divOrElementThatNeedsBackgroundImages { print-color-adjust: exact }" instead, print-color-adjust is compatible across browsers as of 2023. [MDN link](https://developer.mozilla.org/en-US/docs/Web/CSS/print-color-adjust) – Sunny Jul 17 '23 at 22:55
  • Can't load the background image for the first time while printing. It loads in the next attempts – Büşra Güler Aug 01 '23 at 00:24
193

Browsers, by default, have their option to print background-colors and images turned off. You can add some lines in CSS to bypass this. Just add:

* {
    -webkit-print-color-adjust: exact !important;   /* Chrome, Safari 6 – 15.3, Edge */
    color-adjust: exact !important;                 /* Firefox 48 – 96 */
    print-color-adjust: exact !important;           /* Firefox 97+, Safari 15.4+ */
}
Toothbrush
  • 2,080
  • 24
  • 33
Kevin vd Bosch
  • 1,931
  • 1
  • 8
  • 4
  • ya works fine but mozilla mark as non standart _This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future._ – Qh0stM4N Feb 13 '18 at 12:32
  • 11
    Why is the `!important` necessary? –  Mar 05 '18 at 06:57
  • Worked for me! Thank you. – Nick Woodhams Mar 25 '19 at 01:44
  • 1
    `color-adjust` is not properly supported by FireFox unfortunately. It seems to apply only to background, not to the `color` css property. It is reported as a [bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1436758), without much activity or votes. Keeping the background is quite useless if the font color is not preserved, causing it to be unreadable. – Frédéric Jun 16 '19 at 14:51
  • It's a good solution. Just keep in mind that it does not work with IE11 (I know!). – Rafael S. Fijalkowski Jul 24 '20 at 09:46
  • It's working in 2020 now. Maybe non-standard features are unofficially standards now! I couldn't find any other good solution than this. Who cares about the IE now. All browsers are Chromium or Firefox variant! – Mahmudul Hasan Shohag Aug 25 '20 at 20:04
  • 3
    the `!important` was not necessary for me – Kip Nov 09 '21 at 19:52
  • This is a fantastic solution. Works in both Firefox and Chrome browsers, contrary to previous comments. – Speednet Jun 29 '22 at 12:48
  • better than nothing.... – Bret Weinraub Feb 23 '23 at 11:22
  • This works, but seems that the user is not allowed to unclick "background graphics" checkbox, which is also not optimal - the graphics are applied for good. – mnc Jun 19 '23 at 13:33
81

I found a way to print the background image with CSS. It's a bit dependent on how your background is laid out, but it seems to work for my application.

Essentially, you add the @media print to the end of your stylesheet and change the body background slightly.

Example, if your current CSS looks like this:

body {
background:url(images/mybg.png) no-repeat;
}

At the end of your stylesheet, you add:

@media print {
body {
   content:url(images/mybg.png);
  }
}

This adds the image to the body as a "foreground" image, thus making it printable. You may need to add some additional CSS to make the z-index proper. But again, its up to how your page is laid out.

This worked for me when I couldn't get a header image to show up in print view.

ckpepper02
  • 3,297
  • 5
  • 29
  • 43
  • 3
    This was an awesome solution for what I needed to do, which was switch an inline `` (for RWD) with a different one for `@media print`. The web image was on a dark background, so printing that image didn't work on white paper, and I didn't want to force users to print a dark background on the header. Perfect! – JHogue Oct 11 '13 at 18:50
  • 5
    While this isn't a "correct" answer. It is FAR more helpful than the accepted answer. – Xenology Jun 24 '14 at 19:44
  • below answer http://stackoverflow.com/a/15208258/915865 should be marked since it has better explanation, imho – Kat Lim Ruiz Jul 02 '14 at 21:06
  • 1
    In firefox it worked only if you used content inside :before like@hanz answer – vaskort Jul 15 '15 at 13:04
  • I don't understand how `content` does anything without `::before`/`::after`? Everything I've read says that property only works when it's inside a before or after pseudo selector, so it seems like the code shown here (with just a "body" selector) wouldn't do anything unless you add a `::before`, as in @hanz's answer. – machineghost Jul 10 '18 at 20:08
  • Nice solution! no issues. – Ghazi May 02 '20 at 04:35
53

You have very little control over a browser's printing methods. At most you can SUGGEST, but if the browser's print settings have "don't print background images", there's nothing you can do without rewriting your page to turn the background images into floating "foreground" images that happen to be behind other content.

Marc B
  • 356,200
  • 43
  • 426
  • 500
24

The below code works well for me (at least for Chrome).

I also added some margin and page orientation controls.(portrait, landscape)

<style type="text/css" media="print">
@media print {
  body {-webkit-print-color-adjust: exact;}
}
@page {
    size:A4 landscape;
    margin-left: 0px;
    margin-right: 0px;
    margin-top: 0px;
    margin-bottom: 0px;
    margin: 0;
    -webkit-print-color-adjust: exact;
}
</style>
Tarik
  • 4,270
  • 38
  • 35
10

Make sure to use the !important attribute. This dramatically increases the likelihood your styles are retained when printed.

#example1 {
    background:url(image.png) no-repeat !important;
}

#example2 {
    background-color: #123456 !important;
}
nuts-n-beer
  • 255
  • 4
  • 8
  • I created some simple "printer friendly" reports for my company using this method. It works on OS X Chrome/Safari and Windows 8 Chrome/IE (haven't tried any other platforms). – nuts-n-beer May 19 '15 at 16:16
  • 4
    This appears to have no effect on Chrome, Firefox, and Safari on Mac. – intcreator Jul 09 '16 at 00:12
  • This is just what I needed to apply the attribute to every usage of that particular element and let me print the doc appropriately. Thanks! – johnny Dec 17 '19 at 20:45
7

Like @ckpepper02 said, the body content:url option works well. I found however that if you modify it slightly you can just use it to add a header image of sorts using the :before pseudo element as follows.

@media print {
  body:before { content: url(img/printlogo.png);}
}

That will slip the image at the top of the page, and from my limited testing, it works in Chrome and the IE9

-hanz

hanz
  • 141
  • 2
  • 1
5

Use psuedo-elements. While many browsers will ignore background images, psuedo-elements with their content set to an image are technically NOT background images. You can then position the background image roughly where the image should have gone (though it's not as easy or precise as the original image).

One drawback is that for this to work in Chrome, you need to specify this behavior outside of your print media query, and then make it visible in the print media query block. So, something like this...

.image:before{
        visibility:hidden;
        position:absolute;
        content: url("your/image/path");
    }   

@media print {
.image{
   position:relative;
    }
    .image:before{
       visibility:visible;
       top:etc...
    }       
}

The drawback is that the image will often be downloaded on normal page loads, adding unnecessary bulk. You can avoid that by just using the same image/path you'd already used for the original, visible image.

Dtipson
  • 1,564
  • 16
  • 21
4

Browsers, by default, have their option to print background-colors and images turned off. You can add some lines in CSS to bypass this. Just add:

* {
    -webkit-print-color-adjust: exact !important;   /* Chrome, Safari */
    color-adjust: exact !important;                 /*Firefox*/
}

Note: It's not working on the entire body but you could speciy it for a inner element or a container div element.

Umar Asghar
  • 3,808
  • 1
  • 36
  • 32
3

it is working in google chrome when you add !important attribute to background image make sure you add attribute first and try again, you can do it like that

    .inputbg {
background: url('inputbg.png') !important;  

}

Hady El-Hady
  • 347
  • 3
  • 7
  • good point to mention, solved my issue together with -webkit-print-color-adjust: exact !important; – czmarc Sep 18 '18 at 20:09
1

https://gist.github.com/danomanion/6175687 proposes an elegant solution, using a custom bullet in place of a background image. In this example, the aim is to apply a background image to an a element with class logo. (You should substitute these for the identifier of the element you wish to style.)

   a.logo {
     display: list-item;
     list-style-image: url("../images/desired-background.png");
     list-style-position: inside;
   }

By including this within a

@media print {
}

block, I'm able to replace a white-on-transparent logo on the screen, rendered as a background-image, with a black-on-transparent logo for print.

Martin Smith
  • 3,687
  • 1
  • 24
  • 51
  • This is a cute fix, but it doesn't really work if the background image is much larger than the container. (it stretches out my containing div) – Jabbamonkey Oct 30 '19 at 04:34
  • I do not get it! To which element should I set those styles?! I do not have an "a" element or a "logo" class! – Eslam Sep 14 '22 at 23:44
  • Use the element and class of the element that you wish to have a background image. This example assumes you want to style an `a` element with the class `logo`. Add a new class (named as you wish) if necessary. – Martin Smith Sep 15 '22 at 08:46
0

You can use borders for fixed colors.

 borderTop: solid 15px black;

and for gradient background you can use:

    box-sizing: border-box;
    border-style: solid;
    border-top: 0px;
    border-left: 0px;
    border-right: 0px;
    border-image: linear-gradient(to right, red, blue) 100%;
    border-image-slice: 1;
    border-width: 18px;
-4

You can do some tricks like that:

<style>
    @page {
        size: 21cm 29.7cm;
        size: landscape
        /*margin: 30mm 45mm 30mm 45mm;*/

    }
    .whater{
        opacity: 0.05;
        height: 100%;
        width: 100%;
        position: absolute;
        z-index: 9999;
    }
</style>

In body tag:

<img src="YOUR IMAGE URL" class="whater"/>
Saeid Shakiba
  • 35
  • 2
  • 7