CSS Image Replacement Class
I’ve been using this handy CSS image replacement technique for a while now, so I thought I’d share it. It’s nothing revolutionary, as similar approaches have been documented by others, but the way I do it makes it a no-brainer - and I need all of the available brain-power I can get.
The CSS
.ir {
background: no-repeat 0 0;
display: block;
height/**/:/**/ 0 !important;
overflow: hidden;
}
h1#myID {
background-image: url(/images/h1_myID.gif);
height: 19px;
padding-top: 19px;
}
The HTML
<h1 id="myID" class="ir">Text to be replaced</h1>
So how does it work?
The image replacement happens like this:
- Set the
heightof the element to0. - Set the
background-imageof the element (our image we want to replace the text with). - Add
paddingto the top of the element equal to the height of the image you want to replace the text with (in this case19px). This padding will reveal our background image. - Set the
overflowtohiddenwhich hides the text (now sitting below the background image).
Still no comprendé?
Let’s run through it line-by-line — CSS first.
Firstly, the class .ir is short for “image replacement”.
background: no-repeat 0 0;no-repeatstops our background image from tiling, and0 0positions the background0pixels from the left and0pixels from the top (in that order).display: block;- Most image replacement is done on headings, but occasionally you might decide to image replace an anchor. Adding
display:blockwill allowpadding:topto be applied to anchors in this case. height/**/:/**/ 0 !important;- Warning! Warning! Hack alert! Yes there’s a comment hack in there, but it’s unobtrusive, fixes an IE 5.x browser issue, and won’t break in future - so it’s fine in my book. What this line does is set the
heightof the element to0in all browsers except IE 5.x. We add!importantto override theheightwe’ll set on the id of ourh1in an upcoming step. overflow: hidden;- Since our element now has a
heightof0, we want to hide anything that flows beyond that - namely our text.
Now onto the CSS for our h1. We usually want unique headings, so we start by giving our h1 an id - in this case myH1.
background-image: url(/images/h1_myID.gif);- Here we set our background image (the image we want our text replaced with). Everything else (the tiling and position of the background image) has already been set up by the
.irclass. height: 19px;- This is the height mentioned earlier. Since IE 5.x browsers ignore our
padding-top, we have to feed them a height. This height will only be rendered by IE 5.x browsers however, as we overrode this height in our.irclass withheight/**/:/**/ 0 !important;. Our.irclass is a class, so it needs that!importantin there to override ourh1id. padding-top: 19px;- All other browsers will happily apply
padding-top, and this will make our background image pop up and appear. Voilà - image replacement! Here’s a sample I prepared earlier.
I thought you said this was easy?
Nope - I said it was a “no-brainer”. What makes it a no-brainer is that the image replacement is all nicely bundled up in a simple class. All you need to do to replace text with an image is to give your element a unique ID and our .ir class, then set the height and background image for your element and you’re done.
As I said - nothing ground-breaking, but still handy nonetheless.
Are there any other applications for this?
There sure are. Keep an eye out for my next post which uses the .ir class to create funky CSS based image rollovers! That’s right - rollovers! The ground-breaking continues!
I’m always keen for feedback, so don’t be shy - let me know what you think
November 29th, 2006 at 8:46 pm
I have been using something similar to this for a while. However, the adding a class to elements is mixing presentation with content. This should be avoided, the same with the clearfix class for easy clearing. Instead of adding an extra class to the physical markup, simply use the appropriate selector.
I also prefer the Phark image replacement technique. Below is some sample code, which I use… (not hacks required!)
#branding h1 a,
#navigation li a {
display: block;
overflow: hidden;
font-size: 0.0; line-height: 0.0;
text-decoration: none; text-indent: -9999px;
background: transparent no-repeat 0 0;
}
#branding h1 a {
height: 50px; width: 350px;
background-image: url(header.gif);
}
#navigation li a {
height: 20px; width: 150px;
background-image: url(navigation.gif);
}
Then you can, of course, you the same image for all the navigation, and simply move it around, etc.
#navigation li.about a {
background-position: 0 -300px;
}
November 29th, 2006 at 8:53 pm
You don’t need the height hack, the overflow rules, or the padding.
November 29th, 2006 at 8:54 pm
Oops, meant to provide a URL to it in working practice - http://www.sussexsportmc.co.uk/css/defaults.css and http://www.tlc.ac.uk/css/master.css both show the image replacement described above. As well as the best practices with the easy clearing fix.
November 29th, 2006 at 9:16 pm
Interesting solution, it still doesnt work/display the text when the images are turned off and has the same issues with text overlapping the box’s extremities and dissapearing.
November 29th, 2006 at 10:22 pm
Thanks for the feedback - some interesting comments (which I like to see).
@Trovster: You’re right - this is mixing presentation with content, but sadly I’m stuck in the trenches of the corporate web design world - and that means IE 5.5 and 5. Since you can’t use :after in anything earlier than IE 7, this solution has been the way to go for me. I’m not so keen on Phark, simply because of the nasty outlines it causes in Firefox when clicking an image replaced link - that’s the only reason though
@Andy - Setting a height of 19px on the text and overflow to hidden shows 19px of text. Add padding to the top and a background image, and you’ve got a background image with 19px worth of text sitting beneath it. So the hack forces the height to be 0 in browsers later than IE 5.5 (which hides the text), but not in older browsers which require the height.
@Trovster - Great CSS. I think Leevi Graham has borrowed heavily from you in the past (I worked with Leevi at Izilla before he deserted us).
@Mark - I have a bit of a laissez-faire attitude towards images being turned off… Not sure what you mean by “text overlapping” issues, but I’m interested in finding out if you’d like to explain.
November 29th, 2006 at 11:46 pm
@Trovster: I just remembered - Phark breaks in IE 5. It indents the background image along with the text, and there’s no fix for that I’m aware of…
November 30th, 2006 at 2:44 am
Thanks
Aslong as image replacement have no extra html it’s good for me.
November 30th, 2006 at 4:54 am
@Wayde: I’m not using :after for image replacement, it is a tried and tested solution for easy clearing of floats.
Secondly, you should notice the overflow: hidden; in my Phark image replacement code. This cuts back the :focus outline, so it is neatly around the link, and not extending to the edge of the browser, meaning it behaves more like FF1 and IE6.
I don’t understand why targeting for IE5 and IE5.5 mean you can’t use selectors, and are stuck with adding extraneous, presentation-driven classes. But it’s not really a major biggie, just not needed.
As you can see on Approved Design and Tamworth & Lichfield College website, the image replacement (Phark) does work in IE5 (well, it did on my MultipleIE test version).
Ahh, Leevi Graham, that Aussie guy… in a weird turn of fate, I’ve met that dude a few times, as he’s a part of the Multipack! It’s a small world/web!
November 30th, 2006 at 8:57 pm
if you turn off images you should still be able to see the text underneath - there are solutions to achieve this but these solutions have the same issue. If you increase the font size in the browser the text doesnt expand the containing area (because they use overflow:hidden) so theyre not accessible. i use a more complex version on most of my sites that retains this issue but would really love a solution that is accessible!
November 30th, 2006 at 9:41 pm
The Gilder/Levin replacement technique (the extraneous span) provides a solution for images-off/css-on combination. However, you can’t use transparent images, and you mentioned the overflow:hidden; and increasing font-size issue, as well.
It is widely accepted the images-off/css-on combination is a mute point and it certainly isn’t a problem that should be grouped with accessibility. This combination is a choice, and something the user can control. The site is perfectly accessible if the stylesheet is turned off. This also allows for the scaling of text (to what ever size you deem fit!).
In the Introduction to Web Accessibility by the W3C it says the following:
“Millions of people have disabilities that affect their use of the Web. Currently most Web sites and Web software have accessibility barriers that make it difficult or impossible for many people with disabilities to use the Web.”
As you can see it’s about disabilities which affect use, not based on arbitrary choices. images-off/css-on is one of these choices which can affect the usability of a website, but not the accessibility of one.
It is for these reasons why I stick with the Phark (text-indent: -9999px;) replacement technique. It is accessible, works cross-browser and doesn’t require extraneous markup.