No Mod Required

An Alernative to Negative Text Indent for Image Replacement - CSS

I’ve never been a fan of the negative text indent trick for image replacement. Don’t get me wrong, it’s a great technique and is very useful, I’ve just never liked it. Something about setting those crazy negative margins always struck me as incredibly hacky (even though it really isn’t,) so I never fully felt comfortable with the technique. I can’t really explain it, but that’s the reality.

Anyway, today I was looking at implementing an image replaced H1 on a site I’m developing and somehow, some way I was struck by a tiny bolt of inspiration and realized that, as long as my browser targets were reasonable (Firefox, IE6+, Safari, Opera 9+), I could use opacity to get the same result. That, for whatever reason, seemed like a better solution to me, so I went ahead and tried it. This post is the result…

If you want to see an example- like Madge said, you’re soaking in it. I implemented it here tonight. I walk on the wild side.

Here’s the markup for the image replaced <h2>*:

<h2 id="logo" ><a href="/" title="home">DrunkenFist.com</a></h2>

Here’s the css in my main sheet:

#logo{
position:absolute;
width:629px;
height:147px;
z-index:1;
left: 0px;
top: -4px;
background-image: url(/img/logo.gif);
}
#logo a {
display:block;
width:200px;
height:50px;
opacity:0;
background:transparent;
}

The interesting bits are the opacity and background definitions. Opacity:0, should be pretty self explanatory. It sets the opacity of the anchor tag to 0. That’s what hides the text. Opacity is supported by Firefox, Opera 9.0 (the Wii is covered) and Safari. I’ve not gone to town researching how far back Firefox and Safari support go, but I’ve seen it work in 1.* versions of both, so I’m pretty comfortable with support there. Setting the background to transparent was necessary to make the entire block clickable. Before I set that the only clickable area was where the invisible text was. If you’ve ever done any Flash development, it was like turning text into a button and neglecting to set a proper hit area. I’m not really sure why that was the case. I’d like to take some time to play around with variations to maybe see what’s what.

As these things inevitably go, it was necessary to set some IE specific styles to make this work in Microsoft’s pride and joy. Here’s that markup as it’s implemented now**


<!--[if gte IE 5.5]>
<style type="text/css">
#logo a {
filter:Alpha(opacity=0);
background:url();
}
</style>
<![if lt IE 7]>
<link rel="STYLESHEET" type="text/css" href="/css/ie.css" />
<![endif]>
<![endif]–>

Again, there are two interesting bits (maybe three if you’re not familiar with conditional comments. Conditional comments rule the school.) The first is the IE specific filter:alpha(Opacity=0), which is the equivalent*** of the straightforward opacity definition used above. The second is the best I can do IE-wise to set a transparent background since IE doesn’t support transparent as a value. There’s got to be a better way to do that, but it’s not coming to me at present (any suggestions?)

And that’s it. I’m a little bit insane right now from hurriedly typing this thing out in the last hour and a half, so I’m sure I’ll look at this in the morning and want to rework it, but until then, this will have to do.

*I use an H2 for this and not an H1 since:

  • I already get top placement for both my name and my domain name, so stuffing an H1 with either isn’t really going to give me any real benefit and using anything else doesn’t really make sense if I actually want to use the H2 as a home link for PDAs and text/voice browsers
  • I like using H1s for the topic of the page. Even if I’ll never get top placement for “Movies” it just makes semantic sense for me to have that be the top of the content tree
  • My logo (and menus) are at the very bottom of my markup (this is more readily apparent in the markup of my main site, which starts almost immediately at the H1), so stuffing an H1 down at the bottom just feels plain wrong to me…

**I have to clean this up and get the styles out of the document. It’s templated, so including the styles on a document by document basis is easy, I just hate obvious loose ends like this (especially since there are so many loose ends around here.) I just haven’t had any instances where I had IE specific code that needed to run on IE7 as well as IE6, so I didn’t have an elegant solution for such an eventuality.

**It should be noted that Opacity and the Alpha:filter aren’t exactly equivalent as they use two separate scales. Since 0=0, it doesn’t really matter what those differences are for the purposes of this article. When it’s not so late and I’m not so tired, I’ll write up a little bit on cross-brower Opacity.

Leave a Reply

Note: Wrap all of your code blocks in <code>...</code> and replace < and > with &lt; and &gt;, respectively.