Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Image Replacement Technique

What is the best (as in cross-browser) technique to do image replacement in CSS? I am using sprites to do my navigation, but I want the markup to remain SEO friendly. Given the following HTML structure...

 <div id="menu">
   <ul>
     <li><a href="#">Test</a></li>
     <li><a href="#">Tester</a></li>
     <li><a href="#">Testing Testing</a></li>
   </ul>
 </div>

What is the best way to replace the text with a background image using CSS only?

I am currently using this...

text-indent: -9999px;

But, it fails with CSS on, and images off.

like image 560
Josh Stodola Avatar asked Aug 04 '09 03:08

Josh Stodola


4 Answers

In 2008, Google's presentation at An Event Apart made it clear that valid image replacement will not be penalized by Google. See Mezzoblue's post about it

Basically, as long as the image you replace the text with has the same text in it, it will be considered valid and not trying to cheat search engines. How do they determine whether the image is valid or not? I have no idea... OCR? Manual review?

As far as CSS on/images off, there is no perfect solution, all of them require extra non-semantic markup. See the css-tricks link that beggs posted on the different techniques. I personally do not bother with the very small percentage of users who browse with CSS but no images.

Your choice is simple. Extra markup, or don't care about css on/images off.

like image 41
kmiyashiro Avatar answered Sep 20 '22 14:09

kmiyashiro


I just came up with this, it seems to work in all modern browsers, I just tested it then on (IE8/compatibility, Chrome, Safari, Moz)

HTML

<img id="my_image" alt="my text" src="images/small_transparent.gif" />

CSS

#my_image{
  background-image:url('images/my_image.png');
  width:100px;
  height:100px;}

Pro's:

  • image alt text is best-practice for accessibility/seo
  • no extra HTML markup, and the css is pretty minimal too
  • gets around the css on/images off issue where "text-indent" techniques still hide text for low bandwidth users

The biggest disadvantage that I can think of is the css off/images on situation, because you'll only send a transparent gif.

It might be possible to write a little javascript to help out with this, replacing all the image sources with their background-image css properties. But this would only work if the browsers still attaches css properties to elements and then ignores them. I don't know if this is the case or not, I'll have to test it out. You'd also want to develop a javascript-based test to see if css is being applied to the page (maybe check the position of some test element).

btw, I'd like to know, who uses images without stylesheets? some kind of mobile phone or something?

edit:

Based on comment below... inline styles hrm... maybe I should just make a php helper function like <?php echo css_image('image_id','my text','image_url');?> to generate some code like this:

HTML

<div id="image_id" style="background-image:url('image_url')" class="image">
<img src="image_url" class="alt_text" alt="my text" />
<p>my text</p>
</div><!--/#my_image-->

then just attach some CSS in the stylesheet

#image_id{width:*image width*;height:*image height*}

.alt_text{position:absolute;top:0px;left:0px}
.image{display:block;background-position:left top}
.image p{position:absolute;left:-9999em}

it's an older technique that I'm using, not sure where I found it though. It works with CSS on/images off, CSS off/images on, CSS on/images on.

If a user with CSS off/images off visits, they'll see doubled up text. If a search engine spider visits, they'll see alt text and regular text, an intelligent spider could easily identify this for what it is, an innocent image replacement technique.

So, this technique is worst for screen readers, since alt text is read, but these users should be able to skip to the next paragraph, which is why I stuck <p></p> around "my text".

Everyone else with both CSS and images turned off is some kind of bot, right?

like image 30
David Meister Avatar answered Sep 17 '22 14:09

David Meister


If this is the html:

<div id="menu">
  <ul>
    <li><a href="#" id="home">Home</a></li>
    <li><a href="#" id="about">About</a></li>
    <li><a href="#" id="contact">Contact</a></li>
  </ul>
</div>

And this is the css:

#menu ul li a{
  display: block;
  overflow: hidden;
  text-indent: -9999px;
  background: transparent url(yourpicture.png) no-repeat 0 0;
  width: 100px;
}
#home{
  background-position: 0px 0px
}
#about{
  background-position: -100px 0px
}
#contact{
  background-position: -200px 0px
}

The image would then be 300px wide, and each tab would be 100px wide.

like image 184
Marius Avatar answered Sep 18 '22 14:09

Marius


The background image is usally applied to the <a> link, giving the entire clickable area an image. To hide the text you can use a very big negative value for text-indent.

like image 29
Luca Matteis Avatar answered Sep 16 '22 14:09

Luca Matteis