A client recently brought to my attention an issue that I always said I was going to look into more closely, but somehow just never really got around to it: print CSS.
We all know we should be doing it, but how many of us really go through our projects, page-by-page, clicking Print Preview? Well, I know I hadn’t really done much at all.
And so it is no wonder I had not come across the issue with background images before.
I think most browsers have Print Background unchecked by default, which means probably an enormous percentage of users never see our background colors or images. Getting around light-colored text that should appear in front of a background color is easy, but what about background images? You know, like graphic headers and such…
The obvious solution was to exchange the background images for good-old <img> tags, but that would mean breaking apart all those sprites I worked so hard on, and losing all the benefits of using sprites, right?
Turns out, no. Here’s what I did…
Previously, I had HTML something like this:
<h1><a href="...">This is my header</a></h1>
And CSS like this:
<style>
h1 {
width: 100px;
height: 30px;
background-image: url('mysprite.png') 10px -100px no-repeat;
}
h1 a{
width: 100px;
height: 30px;
display: block;
text-indent: -9999px;
}
</style>
Right? The <h1> has the background image, positioned, and the text inside the <a> is pushed off screen, so it doesn’t interfere with the background image.
Now, I have HTML like this:
<h1><a href="..."><img src="mysprite.png" alt="This is my header" /></a></h1>
And CSS like this:
<style>
h1 {
width: 100px;
height: 30px;
}
h1 a{
width: 100px;
height: 30px;
display: block;
overflow: hidden;
}
h1 img {
margin: -100px 0 0 10px;
}
</style>
By placing the image inline, the print CSS will see it and print it. But I can still use my sprited image as the src of the <img> tag: by using the margin, in conjunction with the overflow: hidden, I can move my image around inside the <a>, as if it were still a background-positioned image. And, I still get all the benefits of using sprites, because once the sprite is used for one <img>, it is cached and will not be fetched again for the next <img>…
And of course, where I previously had inline text for accessibility and SEO reasons, but positioned off-screen for readability, I now have alt text, so no loss there either!
Just thought I’d share, happy CSSing,
Atg
Great, great article, you are a hero! I had never thought of using sprite maps without background image.
I thought I would share this because I had a unique problem that was solved by this issue. I was using a webkit CSS feature called -webkit-print-color-adjust: exact; which allows background-images and color to be printed in spite of the default print behavior which is to ignore them
After putting this app together, I ran into this immeasurably painful issue where the background-image, when printed, would scale and stretch to a huge, out of place image. I was using a sprite map – tried both PNG and SVG images. I couldn’t use backround-size because of I wanted to use only a portion of the sprite for the specific CSS class. Ultimately, I could not find a solution to this scaling issue.
So, my CSS background image would scale uncontrollably when I would print. Using an IMG-tag based image map with margins instead allowed me to solve this printing background-image scaling and stretching issue.
Again, thanks for the brilliant idea!
Great article !!!!