Outline property for image-replaced links

In the previous article about the annoying outline, I introduced you the JavaScript based solution. After a few days, Nathan Smith came with the much more elegant outline: none; trick. The question remains, how should we apply it in a way not to confuse a user browsing with a keyboard?

Why does all this happen?

If we shift text somewhere far to the left side, with the Phark image-replacement – the text-indent: -9999px; trick, a content box is also stretched. Ouch!

Negative indentation will not remove the text node from a document flow, like for example what position: absolute; would do. A link must be set to display: block; so we can click on the area, surrounding the link text. This means that it should occupy the whole available parent element area.

What do we want to do here, exactly?

  1. Remove text form a link and replace it with a background-image
  2. Remove the outline border when an image-replaced link is clicked
  3. Keep the outline border when an image-replaced link is focused
  4. Control dimensions of the outline border

The replacement

First, the well known image-replacement trick:

a { background: url("cool_image.gif"); text-indent: -9999px; }
a:visited { background: url("cool_image_visited.gif"); }
a:hover,
a:focus { background: url("cool_image_hover.gif"); }

Remove the outline

We shouldn’t remove the outline completely for the a element, because we are then falling into a trap to confuse a keyboard users. What we should do, is to apply the rule only if we are sure a site is navigated with a mouse. The only way we can detect mouse with CSS is pseudo-class :hover. If something is going to be clicked, it must be hovered first, right? Right. We add the a:hover { outline: none; }:

a { background: url("cool_image.gif"); text-indent: -9999px; }
a:visited { background: url("cool_image_visited.gif"); }
a:hover,
a:focus { background: url("cool_image_hover.gif"); }
a:hover { outline: none; }

Control the outline area

Now, if you hover and click, there’s no outline border, but if you focus it with a keyboard, the outline remains, but is stretched all the way to the left. Fortunately, the overflow: hidden; will do the trick. So, the full set of rules is like follows:

a { background: url("cool_image.gif"); text-indent: -9999px; overflow: hidden; }
a:visited { background: url("cool_image_visited.gif"); }
a:hover,
a:focus { background: url("cool_image_hover.gif"); }
a:hover { outline: none; }

Thinking about the different scenarios is the only way to do the CSS.

Marko Dugonjić is a designer specialized in user experience design, web typography and web standards. He runs a nanoscale user interface studio Creative Nights and organizes FFWD.PRO, a micro-conference and workshops for web professionals.

Interested in more content like this?