If you are reading this, please get modern browser.
skip to main content | skip to main navigation | skip to secondary content

Outline property for image-replaced links

~ 20th January 2006. · 12:05 CET · permanent link · printer friendly ~

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.

9 Comments

  1. I don’t recommend the outline: none; technique. Simply adding overflow: hidden; solves this spilling over of the focus halo. As I mentioned in Nathan Smith’s article.

    For me this makes perfect sense for a solution. overflow: hidden; stops this happening, and is easy to understand and apply to other methods.

    I haven’t seen the halo appear on :hover, only on :focus, or “onmousedown". So adding outline: none; to that seems pointless.

    Removing this halo effect breaks usability, especially with keyboard navigation, as tabbing to links doesn’t show the halo of which is currently active.

    Sidenote: Why do you quote your background images? It’s optional, and breaks support for IEmac. Although it’s a deprecated browser, those extra bytes aren’t needed.

  2. Why don’t we just ask Mozilla to fix it since it’s the only browser that is rendering it wrong?

  3. As I commented on Nathan’s article, take care to hide the overflow:hidden rule from IE5/Mac as it will hide the entire element. For example, your entire masthead above the navigation is mysteriously missing in IE5/Mac.

  4. I didn’t read your last article, but it’s nice to know there is an easy way to remove that outline. While in most cases, I think it’s perfectly appropriate to have a dotted outline around the clicked link; there has been times when I wished I could get rid of it.

    As for the actual implmentation, placing the outline:none on the :hover pseudo class sounds silly. It’s not the hover that causes the outline, it’s the click. What a weird implementation, sounds like a bug to me.

    For the record, I did play around with this just to verify it is indeed :hover that needs the value and not the :active pseudo class…I’ve always got to try it myself ;)

  5. I see no problem in removing the active and focus default borders so long as they are re-styled in a way that is obvious to the user. After all we remove the default underscore on links without a second thought.
    I have several demos on my site that show how to remove the dotted borders in FF and IE, which also allow the introduction of non rectangular, non-overlapping links.

  6. You make a good point, that we don’t want to alienate people that are using the keyboard for navigation. If we hide that outline, alternative means of showing active links should be provided. For now, I’m just leaving the outline on my sites. I just thought people might want to be aware of the ability to hide it, if absolutely necessary.

  7. Why even use this technique? I have always prefered to use “display” .

    eg:
    <h1 class="logo"><span>text</span></h1>

    h1.logo {background….}
    h1.logo span {display: none;}

    Yes is adds another line in the css, but then the text is not visable at all in a css enabled browser but is there for screen readers. Its also less code overall, because you dont have to include any uncessary javascript.

  8. Pogdesing, the display: none; technique acctually prevents screen readers to access text.

  9. great article!
    i was looking for a way to do that, exactly like you shown right here. but i just got one problem doing that.
    well. i’m changing my website to a tableless code looking for a better accessibility too.
    as you can see on my website (http://konb.org) the “hit area” for my links are on the word only. and if using a “display: block” there, the hit area is available on the entire width of menu (not just over the words)

    does anyone have an idea?

    i’m sorry if you cant understand my english
    thank you anyway

Sorry, the comment form is closed at this time, but if you have anything to say, please send me a message.

* Please keep in mind that this is a personal web site and it does not reflect the position or opinion of my respective employers, organizations or partners.

Typetester – compare screen type Supported by Veer.

What is this?

A web log of Marko Dugonjić, web professional from Croatia. Topics covered:

Translate this site

German, Spanish, Italian, French or Japanese (via).

See you there!

Feel like buying a book?

Try with maratz.com aStore

Worth visiting

top of the page | skip to main content | skip to main navigation | skip to secondary content