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 !!!!