How can I force browsers to print background images in CSS? - css

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?

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

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+ */
}

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.

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.

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>

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;
}

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

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.

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;
}

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.

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;

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.

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"/>

Related

CSS Selectors like :after, :before not shown by printing

i am coding and designing an applicaition and i want that the screen mode looks in print mode same.
Here is a screenshot of the screen version:
And here ist a screenshot of the print version (e.g. on Chrome):
The timeline stripe is set by :before and that won't be printed.
Have someone an idea or an solution? Have someone a guide for css print rules?
I know it has been over a year, but here is what worked for me. When the Print Dialog appears, check to enable "Background Graphics" in the Print Dialog.
Try to put your css rules inside print media query:
#media print {
h2 {
font-size: 14px;
}
}
The problem was to adding twitter bootstrap, in the print query there was following code
*, :before, :after {
color: none !important;
text-shadow: none !important;
background: none !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
So i have override it by:
*, :before, :after {
color: inherit !important;
text-shadow: inherit !important;
background: inherit !important;
-webkit-box-shadow: inherit !important;
box-shadow: inherit !important;
}
And after that: change the color of your elements by !important
I had a similar problem with ::before tag, seems like it is related to enabling background graphics as Abdud suggested above. I found that adding print-color-adjust: exact; to body solved it for my case.
body {
print-color-adjust: exact;
}
Note that Chromium browsers only allow body's descendants to have background color printed. If you have background color on your body set, this solution might not be suitable for you. MSDN's has more information about how to use this property
I had a :before pseudo-class with a background-color above a div.
It was not appearing in the print version.
I don't know why but the solution for me was to set a border-top on the div on them #media print {...} version.

text-shadow and box-shadow while printing (Chrome)

I'm making some printable calendar website using HTML, CSS and JS.
Unfortunately I cannot use CSS property called text-shadow, because shadow behind text prints as solid black text without any blur or transparency.
Same problem occurs when I'm trying to use box-shadow for any div - shadow prints like solid black color with no transparency.
I'm using Chrome with style html {-webkit-print-color-adjust: exact;} to ensure all background colors will be printed.
Any workaround? I would prefer not to use any background image.
Edit:
I don't want to hide shadows, it's very easy of course. I want to have shadows printed correctly.
I realise this is an old question, but just to note that it is possible to make shadows print correctly in Chrome. You need to set both -webkit-print-color-adjust and a filter, as found in this bug thread: https://code.google.com/p/chromium/issues/detail?id=174583
.thing {
-webkit-print-color-adjust:exact;
-webkit-filter:opacity(1);
}
(I prefer to set opacity rather than blur as used in the bug, simply because it seems likely to cause fewer problems).
Note that this will limit the resolution of the print (filter makes it send a rasterised version), so text might become harder to read. If you really want to work around that, I'd suggest duplicating the div (one for the shadow, with the filter hack and transparent text, and another for the text with no shadow)
Here is the solution:
#media print {
.item {
-webkit-filter: drop-shadow(4px 4px 1px #ccc);
text-shadow: 4px 4px 1px #ccc;
}
}
If anyone is looking for a way to avoid rasterizing the content of the element with a box-shadow, this is what I used (extended from #Dave's answer):
.thing {
position: relative;
}
.thing::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-shadow: /* define your shadow here, not in .thing */;
-webkit-print-color-adjust: exact;
-webkit-filter: opacity(1);
}
This creates a pseudo-element at the beginning of the element you want to have a shadow. The pseudo-element is sized the same as the parent and then the drop shadow is applied to it only. That way, the drop shadow can be rasterized while the rest of the content of the parent is not.
There are a few issues if you have borders, if your element doesn't support children, etc. but this works in most cases.
I used all the possible solutions to this but the border shadow(with stepped gradient) would show up on my page, but not when I do a Ctrl+P on the page and either- print the page or save as PDF. I even used-
-webkit-print-color-adjust:exact;
-webkit-filter:opacity(1);
I do the same Ctrl+P on this page- https://css-tricks.com/examples/BodyBorder/kottke.php and it works fine.
Solution: I had to remove the bootstrap.css included at the top of my page for the border shadow to show up on my PDF, or when I print the page.
<link href="/lib/bootstrap-3.2.0/dist/css/bootstrap.min.css" media="all" rel="stylesheet" type="text/css" >
I tried
html {
-webkit-print-color-adjust: exact;
-webkit-filter: opacity(1);
}
But it causes links on PDF non-clickable for unknown reason.
After I change it to the css below, both shadow and link problems are solved.
.thing {
-webkit-print-color-adjust: exact;
-webkit-filter: blur(0);
}
You don't need to compromise your web page to make it look pretty printed. Simply define a print.css that makes the printed view suit your needs.
# index.html
<head>
<link href="/css/print.css" media="print" rel="stylesheet" type="text/css" />
</head>
# print.css
.shadow {
text-shadow: none;
}
For more, Smashing Magazine has a helpful article on How To Set Up A Print Style Sheet.

Can not figure out why this CSS Isn't working. I'm sure it's a simple mistake

I'm trying to take away a white border that is appearing from behind an image on my sidebar. I can't figure out what is causing the white border. I thought it was the padding, and then I thought it was the border. If you visit our home page (http://noahsdad.com/) and look on the side bar under the "new normal" picture you will see a "Reece's Rainbow" image. I'm trying to remove that white around the image. I pasted in the code below, but it's not doing anything. Any thoughts as to what I'm doing wrong?
Thanks.
#text-23 { background: none}
the reason it's not working is the background: none is never getting to the img which has the background set on it (backgrounds don't cascade down they exist in the element and you can have multiple elements layered on top of each other much like a painting. Which has the effect of the background cascading)
#text-23 img { background: none; }
that should resolve your problems. I am assuming that when you call the class textwidget you still want it to append the white background, just not for this instance. So if you set the above it will cascade properly with the correct specificity while leaving the rest of your page alone.
This can also be done by
#text-23 .textwidget img { background: none; }
but that level of specificity is not required. However if you try to just do:
.textwidget img { background: none; }
this will override all of the instances where the background is set on an image in the textwidget container.
You have added the white border yourself by setting the following in line 884 of style.css:
.textwidget img {
background: #fff;
padding: 5px;
max-width: 290px;
}
Simply remove the background declaration. If you only want to remove this instance of a white border, add the following rule:
#text-23 .textwidget img {
background: none;
}
This seems to be the conflicting CSS class.
.textwidget img {
background: white;
padding: 5px;
max-width: 290px;
}
If you want to debug css you should really look into Firebug(a plugin for Firefox) or Opera and use builtin dragonfly
These allow you to rightclick on your HTML page and inspect it.
Go to your style.css file and search for .textwidget img and change the background-color property to none. It is currently set to #FFFFFF which is the hex color code for white and is resulting in the white border or background (precisely).
.textwidget img {
background-color: none;
}

CSS oddities: some properties not interpreted

The problem is that on my website http://dev.gratefulhearttherapy.org/, at least 2 css properties are not showing up as expected:
html {
background: #fff url('images/bg-top-honey-v3.0.jpg') top center repeat-x !important;
}
#bd img {
margin: 0;
padding: 4px;
border: solid 1px #D9D9D9;
}
One background image is missing, and pictures don't have the grey border they're supposed to have.
Yesterday night I was messing with 3 things in my code:
the css file typography-new2.css,
the PHP files elements meta.php, header.php, footer.php, and
the Google Analytics code.
I must have broken something but I can't find what. I tried to pass the website and the css through the W3C validators, I scrutinized the code with Chrome inspector, looking for unclosed tags and such, but didn't find anything.
When using the Chrome inspector, to look at the html element and the img's, the missing css seems absent - not only overridden, but absent.
Any help would be appreciated! With much gratitude.
The issues are in your stylesheet: typography-new2.css
Background not showing:
At the very top you have referenced img before html only separated by comments. So the html rule is actually being interpreted as img html {:
img /* REMOVE THIS LINE*/
/* #import url('http://dev.gratefulhearttherapy.org/themes/gratefulheart/tabs.css'); */
/* All CSS files above will be loaded from this single document. */
html {
margin: 0;
padding: 0;
/* background: #fff; #f9dc91 url(http://dev.gratefulhearttherapy.org/themes/gratefulheart/images/background-sandish-tile.jpg) !important; */ /* #F9D984; */ /* customize_background_color */
background: #fff url('http://dev.gratefulhearttherapy.org/themes/gratefulheart/images/bg-top-honey-v3.0.jpg') top center repeat-x !important;
}
Pictures missing grey border:
You have a line full of *s outside of the closing comment / right before the rule #bd img which is probably why the rule is not being applied.
/********************************
*********************************
* $$ GENERAL TYPES
********************************/
******************************** /* REMOVE THIS LINE */
#bd img {
margin: 0;
padding: 4px;
border: solid 1px #D9D9D9;
}
If you remove the two lines, I think all of your issues should be solved.
Your images are not a direct descendent of #bd, I think that is your problem the CSS code is fine. See #150poundsofdonamites response for the other issue.
If this still doesn't produce the desired result try changing html to body.

css background doesn't show up in ie 6 when using rules like #id.class

i'm making a splash image div that changes the background with different css class, here's rules i defined:
#splash {
height: 130px;
}
#splash.homepage {
background: #F7EECF url("images/splash_home.png") no-repeat 0 0 scroll;
}
#splash.projectspage {
background: #F7EECF url("images/splash_projects.png") no-repeat 0 0 scroll;
}
this works fine in firefox and chrome, but the background somehow doesn't show up in ie 6. The weird thing is, it works for the homepage class but not the projectspage class. so ie 6 seems to interpret these almost identical rule differently. i tried clear the cache, didn't help. i'm quite new to css and ie 6 hacks, so am i missing anythings here?
also another problem that's slightly related to this, it seems it doesn't work in firefox when there is space before the class, like "#splash .homepage", but somehow i see other people's websites using the css with a space. what could be the problem?
update:
i tried to reverse the order of the #splash.homepage and #splash.projectspage, then now projectspage works but not the homepage. It seems whatever is immediately followed by #splash is used.
here are some relevant css & htmls:
#splash {
height: 130px;
}
#splash.projectspage { background: #F7EECF url('images/splash_projects.png') no-repeat 0 0 scroll; }
#splash.homepage { background: #F7EECF url('images/splash_home.png') no-repeat 0 0 scroll; }
#splashtext {
padding: 53px;
height: 40px;
width: 450px;
}
#splashtext h2 {
color: #FFFFFF;
font-family: Georgia, "Times New Roman", serif;
font-size: 20px;
font-weight: normal;
font-style: italic;
}
#splashtext p {
color: #FFFFAA;
font-family: Calibri, Arial, san-serif;
font-size: 14px;
font-weight: normal;
margin-top: 10px;
font-style: italic;
}
<!-- splash, this one does not show -->
<div id="splash" class="homepage">
<div id="splashtext">
<h2>some header</h2>
<p>some description</p>
</div>
</div>
<!-- splash, this one shows -->
<div id="splash" class="projectspage">
<div id="splashtext">
<h2>some other header</h2>
<p>some other description</p>
</div>
</div>
IE6 does not support multiple combined selectors to select elements (#id.class or .class.class, etc). IE6 will ONLY recognize the last class/ID in your chain.
Details and example
However, in this case, as long as you only have .homepage and .projectspage on one element on the page, the background image should be showing up on the correct element.
I noticed that you are probably using .homepage and .projectspage to differentiate between two PAGES and the same ELEMENT on those different pages. A good practice is to put the class on the <body> element so you can use it to differentiate each page and their descendants.
<body class="homepage">
<div id="splash">
Then your CSS would be:
body.homepage div#splash { blah }
body.projectspage div#splash { blah }
Added benefit: you can now target any elements on a per page basis, not just the ones that you add ".homepage" or ".projectspage" to.
It's possible you're having an issue with the .png image files. IE6 cannot handle the transparency layer that is part of .png images, it simply renders any pixel with a transparent marker as a grey background.
As for the second part of your question, #splash.background is a significantly different rule than #splash .background. The first one (no space) refers to the element with id splash that also has a background class. The second rule (with a space) refers to any element of class background that is a child of the element with id splash. Subtle, but important difference.
Try taking out the quotes around your URLs in the background specifiers, or changing them to single quotes.
Why are you worried about ie6? Anyway it works in ie7 and ie8.
Are you sure that is not a problem with png? Try with a jpg or gif image.
I would bet that the problem is specifically to do with the IE6 misshandling of .pngs
To test, try replacing these graphics with a gif or jpg and check to see if the selectors are working correctly.
Once you've identified that it is a problem with pngs try using the Supersleight jQuery plugin.
I think using min-height property will sometimes work.
Try the below code.
#splash {
min-height:130px; /* first */
height:auto !important; /* second */
height: 130px; /* third */
}
#splash.homepage {
background: #F7EECF url("images/splash_home.png") no-repeat 0 0 scroll;
}
#splash.projectspage {
background: #F7EECF url("images/splash_projects.png") no-repeat 0 0 scroll;
}
Note: Please use the same order of css in #splash selector.
(I guess your projectspage is under a sub-directory of home-page?)
Try using absolute paths to each image in the CSS (eg. url("/images/splash_projects.png")) - it chould be that IE6 resolves images relative to the containing page instead of the CSS file (depends whether your CSS is inline or in an external file I suppose.)
I've got the same problem, and it's not PNGs.
e.g.
column2menu li { border-bottom : 1px solid;}
column2menu li.goats { border-bottom-color : brown;}
...works in IE6, but...
td#menu { background-repeat:no-repeat;
background-position:bottom right;}
td#menu.goats { background-image :
url(../images/goats.jpg);}
...doesn't.
But I found a solution for ie6 that works so far in FF, i.e.:
.tdgoats { background-repeat:no-repeat;
background-position:bottom right;
background-image : url(../images/goats.jpg);}
...so you use:
...and ie6 is happy
Thsi post looks OK where I'm typing it, but the preview in the blue box is a bit odd.
Somehow lines 2 and 3 got <h1>'d

Resources