CSS Trick: Turning a background image into a clickable link – Take 2

My previous solution to this was built on Phark’s “Accessible Image Replacement” technique. It works by pushing the text really far to the left (9,999 pixels) which makes sure it’s there for screen readers but hidden from users (unless someone has a display that’s able to show nearly 10,000 pixels to the left of the container in question). The problem seems to be that some browsers, like the one on the iPad, render a 9,999px box even though it’s not visible. This affects performance, especially for animations.

Well, there’s a better way. It works similarly, but instead of pushing the textual content so far left that we’re sure it’s outside the visible area, we push it just outside the box to the right. The advantage is that even without knowing how long the text is, we know exactly how far to push it to make sure it’s completely out of the box. So if you’re asking “How do I make a background image clickable?” This is the new answer. It’s easy, just follow these steps and I’ll show you how to make a clickable background image like this:

Range Web Development

Start with just a link exactly as you would make it for any other purpose, and make sure to give the link an id so that we can use that to apply our styles:

<a href="http://ran.ge/" title="Professional WordPress Development" id="range-logo">Range Web Development</a>

That’s all the (X)HTML you’ll need to make your background image clickable. Your link should look something like this:

So, how can we make a background image a clickable link? It turns out it can be done with a clever CSS trick. Let’s get started by adding the background image and make the link the same size as the image (so you can see the whole image). Since an anchor tag isn’t a block level element, we need to force it to display as “block” so that we can specify the size:

#range-logo {
	background-image:url(http://ran.ge/content/uploads/2009/11/logo-trimmed.png);
	display:block;
	height:100px;
	width:460px;
}

At this point it should look something like this: Range Web Development

Now all we need to do is hide the text. This can be done using “text-indent” to indent the text just outside the containing box, using “white-space” set to nowrap to keep the text from wrapping back into the box, and using “overflow” to hide content outside the box like this:

#range-logo {
	background-image:url(http://ran.ge/content/uploads/2009/11/logo-trimmed.png);
	display:block;
	height:100px;
	overflow:hidden;
	text-indent:100%;
	white-space:nowrap;
	width:460px;
}

And the finished product looks like this: Range Web Development

And there you have it – a quick CSS trick with clean markup that turns your background images into clickable links. The best thing is, these don’t adversely affect your SEO and can even be easily used inside of header tags if needed!

Update:
I was asked how to add a border. Here it is with a CSS border:

#range-logo {
	background-image:url(http://ran.ge/content/uploads/2009/11/logo-trimmed.png);
	border:1px solid #CCC;
	display:block;
	height:100px;
	overflow:hidden;
	text-indent:100%;
	white-space:nowrap;
	width:460px;
}

Range Web Development

That obviously works, but the border is too close for my liking and adding padding causes our image to be out of place. Here’s the solution:

#range-logo {
	background-image:url(http://ran.ge/content/uploads/2009/11/logo-trimmed.png);
	background-position:5px 5px;
	background-repeat:no-repeat;
	border:1px solid #CCC;
	display:block;
	height:100px;
	overflow:hidden;
	padding:5px;
	text-indent:100%;
	white-space:nowrap;
	width:460px;
}

Basically we’re adding 5 pixels of padding all around, re-positioning the background image to 5px in from the top and left, then setting the background image to not repeat. Now our border looks nice:
Range Web Development

As a quick note, if you’re using “box-sizing: border-box;” you’ll need to adjust the width and height in the CSS to be the width/height of the image plus the padding, so in this case 470px × 110px.


Comments (44)

  1. Pingback: » CSS Trick: Turning a background image into a clickable link » BlueDog

  2. I have been trying to make the image have a css border as well, although the border always ends up around the text off to the side.

  3. I have a issue on how to make the top image clickable …. any thoughts? Also maybe you can help with a solution to an additional issue. I have the bottom image set to no-repeat, yet it still repeats on x… and thoughts?

    .footerzig{background: url(“http://www.iselaespanadesignstudio.com/wp-content/themes/twentytenchild/images/zigzagf.png’”), repeat-x scroll 0 0 transparent;
    clear: both;
    height: 154px;
    }
    .footerzigover{background: url(“http://www.iselaespanadesignstudio.com/wp-content/themes/twentytenchild/images/idea.png’”), no-repeat scroll 0 0 transparent;
    clear: both;
    height: 154px;

    }

  4. I have a issue on how to make the top image clickable …. any thoughts? Also maybe you can help with a solution to an additional issue. I have the bottom image set to no-repeat, yet it still repeats on x… and thoughts?

    .footerzig{background: url(“http://www.iselaespanadesignstudio.com/wp-content/themes/twentytenchild/images/zigzagf.png’”), repeat-x scroll 0 0 transparent;
    clear: both;
    height: 154px;
    }
    .footerzigover{background: url(“http://www.iselaespanadesignstudio.com/wp-content/themes/twentytenchild/images/idea.png’”), no-repeat scroll 0 0 transparent;
    clear: both;
    height: 154px;

    }

  5. Thank you for the great css trick! The only thing that makes the text appear again, is searching for it (ctrl+f). But i think no one would do that…

  6. Great trick Aaron! It did the job fine on my drupal site in Firefox.
    In all the other browsers the link kept showing at the right end of the backgroundpicture.

    Nevertheless, thanks so much for sharing!

  7. Hey Aaron,
    Thanks for the code.

    I got a small problem here.
    My idea is to have this:
    BODY
    IMAGE (Clickable)
    WRAPPER (margin: 0 auto)
    Page Contents…

    But my background image link is not working.
    I guess its because of the #wrapper code with “margin: 0 auto” which comes immediately below it.
    z-index changes aint working either.
    Any ideas? This thing is getting on my nerves.
    Thanks in advance… :)

  8. Great solution, thank you!

    If you want to get this to work also in IE6 and IE7, the background image style should not (only) be applied to the a tag, but (also) to a surrounding div container.

  9. This is very nice. I have a question: is it possible to add a _blank “target” in the CSS so that the new page opens in a new window? :)

    • There are CSS properties in the proposed CSS3 spec that are supposed to do this:

      .external-link {
      	target-name: new;
      	target-new: window;
      }

      However, as far as I know this isn’t supported by any browsers yet.

      You can add target=”_blank” to the HTML or add some JavaScript to handle it.

  10. Great trick. I’m trying to use this to have 5 icons in a row but I can’t seem to control their placement. I want to be able to center them in a div, but can’t figure out how.

    Sincerely,
    A css-learner

  11. I prise the Lord for You and Google – thank you Aaron. After a whole day to figure out the problem, you safe me. I have only to use a class instead of an ID in my case and it works wonderful in IE FF and Chrome.

    Best regards
    Marcus

  12. Hi Aaron

    Sorry if this is low level stuff but Ive just created an Image and used Css to display it. No HTML yet.

    }
    #body .header ul{
    background: url(“images/get in touch.jpg”) no-repeat 790px 0px;
    }

    the href in the html is

    href=”contact.html”>

    All id like to do is make the image clickable to this ref.

    Any easy way of adding to the css ?

    Any feedback appreciated
    Bryan

    • First, those CSS rules wouldn’t work without HTML. Specifically you need a ul inside an element with the class header inside an element with the ID body.

      Second, semantically it makes sense to use a link to link something.

      Lastly, you can’t do that with just CSS. You’ll need HTML or JavaScript to link the element that has the images as the background.

      • Thanks for response got around by doing
        this:

        	<div style="position:absolute; top:145px; left:1030px">
                  <a href="contact.html" rel="nofollow"><img border="0" src="images/get in touch.jpg"></a>
        	  </div>

        Was wondering if you knew what was missing from this search code. I desperately want a basic site search field on my site but have had no luck so far. Any feedback would be really appreciated. And once again sorry if its low level stuff but Im literally a nube and teaching myself but this codes got me stumped.

        }

        Go

        }

  13. Instead of using the “text-indent” and “overflow” CSS to hide my text I just did not include any text in my link:

    <a href="home.html" rel="nofollow"></a>

    The image is still clickable and no extraneous text!

    Only tested on IE 8. Maybe I missed the point of the text in the first place? But figured I would share anyways.

    • Forgot to say Thank You! for posting this in the first place. It helped me out a lot.
      Also, I guess I can’t post html in the comment box. I will try again:

      [/lang]

      Simply showing the lack of text within the link.

    • The reason for the text is so that screen readers (and search engines) have text to process so they know what the link is about. Imagine being blind, having the site read to you, and having no text at all for the link in question.

        • Hi, Brett
          Yes, it’s the absolute positioning — it throws off the use of % in test-indent. If you duplicate your width info here, it works again. E.g.:
          width: 364px; text-indent: 364px;
          HTH, Rupert

  14. Hi Aaron, I much appreciated effort of putting up info on a web.

    Any possible thoughts for 4 level dropdown menu based on graphic buttons? Your tip haven’t resolved issue.

    Many thanks in advance for any possibility thoughts.

    Michal.

    • I think I found a possible solution:   Sometimes just needs to talk to yourself and the solutions appears as the answer of UNIVERSE :-) Thank you for inspiration.

  15. I so wish I’d have found your site earlier, love the way you build the code incrementally and add the highlights, so easy to follow. Thanks for posting.

Leave a Reply

*