As you may have noticed, recently I started identifying external links on this website with a little arrow symbol: ⇗. Most people agree that this is a neat idea – little visual cue that tells you the link points to an outside resource. It distinguishes the links to interesting articles from references to my older and less sophisticated rants from the past. I’m doing this via really simple CSS trick which I actually stole from underscorebleach.net:

a[href^="http"]:after { color: gray; content: "\21D7"; font-size: 1.2em; } a[href^="http://terminally-incoherent.com"]:after, a[href^="http://www.terminally-incoherent.com"]:after { content: ""; }

Simple regexp like pattern matching. First rule applies the style to all absolute links (ones that start with ‘http’) while the second one clears it of the more specific links which point back to this website. Any relative links will remain un-styled. Simple isn’t it?

Unfortunately I’m running into an ugly problem with this. If you look at the sidebar for example, you will notice that some of the small button links also have the little arrow applied to them. I’m not really happy with this behavior but I can’t figure out how to prevent it from happening. Of course I could simply put these buttons in a div, and use an overriding CSS rule to disable the formating there but that’s not the point. I just don’t want to apply this style to any image links. My initial instinct was to simply do:

a img:after { content: ""; }

Unfortunately that doesn’t work. Can you tell me why? It doesn’t work because the content style is applied to the A element while the above selects the IMG element. In CSS you always drill down the DOM tree – each time you specify a child element, the style gets applied to that child. Ideally, you would want to have some sort of a parent selector – something like:

a < img { /* stuff */ }

This would mean select element A whose child is an element IMG. But no dice. This is not the way things work. People have been asking for this feature since the beginning of time and it is unlikely that it will ever get implemented. I can sort of see why too - it would just be messy forcing the rendering engine to reverse up the tree and re-cascade all the styles below. Obviously this is not the way to go.

I wish there was a way to select a text only node, since this is precisely what I need here. I want to put the little arrow on all text links, and ignore all image links. So having a text-only selector would be perfect. I'm not the only one who thought about it either. Alastair Campbell for example proposes the following syntax:

a[href^="http"]:text-only { /* stuff */ }

I can totally get behind that notation, and I don't really see huge problems with implementation. Unfortunately, no one at W3C seems to be considering this. It is a problem that is constantly resurfacing. I believe that every time someone decides to identify external links with CSS (which is probably quite often) they bump into this problem and realize that there is no way to solve it in css.

There are workarounds of course. You could for example define a custom class for image links and then make sure you use it every time you actually put one on your page. Something like:

Then you just define a.foo to have blank content and you are home free. Unfortunately if you are like me and you have a website full of image links, you probably won't want to go back and change all of them to use that particular class. In fact, while you are doing this, you might as well just quit using that regexp solution I posted above and simply start marking your external links as class='external' instead and avoid this whole issue all together.

Slightly more elegant solution would be to use JavaScript. If you are using JQuery for example you could just use the :has selector:

$("a:has(img)")

But, do I really want to run a tight loop checking all the links on every single of my pages? It is a performance hit, and yet another script that needs to run before your page is ready for consumption. I'd rather avoid this sort of thing if I can.

So what is your solution? Do you have a clever trick to get around these issues? Do you make your external links with CSS but do not run into the image problem? Let me know. I'd love to see if this can be done properly. :)