Friday, January 27, 2006

Spider stomping 2k6

Spider stomping 2k6
Getting your email address on the web without opening yourself up to 200 spam messages a day is a problem with many possible solutions. There doesn't seem to be a perfect technique, but there are plenty that suffice. This is another sufficient technique that is perhaps the most esoteric and jerry-rigged of them all, but it works (in decent browsers anyway) and I haven't seen it discussed anywhere else, so here it goes.
Address hiding with CSS
One of the most often overlooked abilities of CSS are it's :before and :after pseudo-elements. This is probably because IE doesn't (yet) support them, but this is my hack and I'm not really concerned about IE. These properties allow you to insert content (text, images, etc.) before or after an element. Still more overlooked is the ability of :before and :after to include attributes from the tag they are modifying.
For instance, let's say you'd like to print the URL of links on your page behind the link text so that users know exactly where they'll be headed when they click. By styling links like so a:link:after { content: " <"attr(href)"> "; }, we get a link like this one. Pretty cool, huh? What if you stick your username in the link's title attribute and domain in the rel attribute?
Plain Jane
We can join the two by applying the following CSS: a:link:before { content: ""attr(title)"@"attr(rel)""; }. With no inner text for the a tag, the link now shows up as the full email address, like so: . In the link's href attribute, you can leave your address with the @ replaced by your favorite spam-blocking string ([at symbol] for instance), so that the user can correct it in his mail client and be on his merry way.
JavaScript magic
That's great, but if you want the process to be completely transparent to the user, you'll have to do a little better. With a sprinkling of JavaScript, we can use the onclick attribute to pull the data from title and rel and place a proper address in the href so that it works like normal: . onclick="this.href='mailto:'+this.getAttribute('title')+'@'+this.getAttribute('rel')" You can even use other fancy tools to add the onclicks during the window's onload event and keep your markup nice and clean.
For the purists
So we have an email address that appears as plain text, works like a normal mailto: link, and is invisible to the evil spam bots. The downside is that the tag is actually empty, and when the browser doesn't support the CSS properties we need (MSIE), nothing shows up at all. The fix is simple: just wrap your link text in a span and hide spans that are children of your designated mail links through CSS. You can then use MSIE's conditional comments to show the spans to IE6 and below.
Caveats, notes, etc.
If you want to take a first-hand look at all of the CSS and JS used in this article, just view the source of this page. Nothing is linked externally, so it should be pretty clear. Even in the worst case scenario (MSIE and no JavaScript), it functions as well as any other alternatives and under the proper conditions, you can have your cake and eat it too. One thing to note is that text generated by the :before and :after pseudo-elements is not selectable (at least in Safari). For a really great study of the under-used capabilities of CSS, check out CSS 2.1 Selectors parts 1, 2, and 3 at 456 Berea St.