Clickable Background Images Via CSS

code, css 0 comments suggest edit

On a recent project, my team pursued a CSS based design as we had two sites to build that were similar in layout, but different in look and feel. We were brought in after the schematics and design had pretty much been worked out, but we felt we could work with the agreed upon design.

The site had a typical corporate layout: a header, a body, and a footer. The body might have two or three columns. We started off writing markup that had a structure like so (not including the body columns).

<div id="main">
    <div id="header"></div>
    <div id="body">Body</div>
    <div id="footer">Footer</div>

We set the logo using CSS by applying a background image to the header div.

    background: url(logoExample.jpg);
    width: 180px;
    height: 135px;

Which produces something that might look like this (Trust me, the real thing looks a lot better)…

So everything is fine and dandy till we place the site on a staging server and the client asks that the header logo link back to the main page. This wasn’t in any of the requirements or design spec, but it is perhaps something we could have guessed as it is quite common.

So how do we make the logo image be a clickable link to the main page? My first inclination was to abandon using a background image and make the logo a regular image. The markup would look like (changes in bold)…

<div id="main">
    <div id="header">
        <a href="/"><img src="images/logoExample.jpg"></a>
    <div id="body">Body</div>
    <div id="footer">Footer</div>

But I found a better way to do this based on a technique I saw in “Bulletproof Web Design”. I changed the markup to be like so…

<div id="main">
    <div id="header">
        <a href="/" title="Home"><h1>Title</h1></a>
    <div id="body">Body</div>
    <div id="footer">Footer</div>

I then changed the css for the anchor tag to have the same dimensions as the logo image. I positioned it so that it would fit exactly over the image.

    background: url(logoExample.jpg);
    width: 180px;
    height: 135px;
    position: relative;

#header a
    position: absolute;
    top: 0;
    left: 0;
    width: 180px;
    height: 135px;

#header a h1
    display: none;

Notice that I had to add position: relative; to the header element . That ensures that the absolute positioning applied to the header link is relative to the header and not the entire document.

Now the header logo image appears to be a clickable link. Problem solved. I am pretty sure that others have pioneered this trick, but I hadn’t seen anything written up. What I read applied to making clickable tabs.

UPDATE: As Klevo mentioned in the comments, I really shouldn’t have an anchor tag without any text. Including text would be good for search engine optimization and for those who view the site without CSS. Shame on me, especially after reading the bulletproof book.

But to my defense, it was peripheral to the main point I was making. However that doesn’t excuse it as bad samples have a way of proliferating. So I corrected the sample above. The anchor tag now includes the title of the blog, but sets the title to be invisible.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.



41 responses

  1. Avatar for klevo
    klevo January 12th, 2006

    You should add some text between the A elements. Like a H1 with company name or the page title. It would be good for SEO, semantics and for those who view the site without CSS. To hide the text just add some css class to the H1 element that does display:none;

  2. Avatar for Haacked
    Haacked January 13th, 2006

    Great point! I corrected it.

  3. Avatar for David
    David January 13th, 2006

    So what do you do if you want the logo to appear when you print? Most browsers default to not printing background images and colors.

  4. Avatar for Adam Kinney
    Adam Kinney January 13th, 2006

    Allright, not trying to put you on the spot here, but what makes it better?

    To me, I see that its less obvious what's going on, especially to a developer who inherits the code, and there's more css to parse.

  5. Avatar for Haacked
    Haacked January 13th, 2006

    That's a fair question. It's not necessarily better. It depends on the context.

    My example oversimplifies the real situation. Normally, it would probably be better to have the logo as a real img tag. That would be semantically correct.

    In the real situation, we had a fixed width design and the html I received had the header graphic (which contained the logo on the left, and a big swoosh type thing in the background that extended all the way to the right) as one graphic extending the entire width.

    However on the right side of the header were some links and other dynamic content.

    In this situation, had we known in advance that the logo was clickable, we would have cut this up in a certain way. But to save time (and money), we just slapped it as a background image (so that we could have dynamic content over it).

    Then later, after it was in production, we found out the logo had to be clickable. When changing production, I like to do as little as possible. So rather than recut the graphic and modify the html AND css, we just had to modify the html slightly and the css, no recutting graphics.

  6. Avatar for Haacked
    Haacked January 13th, 2006

    However, there are other reasons this technique is useful. In a blogging engine, for example, you may want to have skins that differ ONLY in CSS and not in HTML.

    This technique might come useful then.

    Also when creating tab interfaces, and you want your tabs to be able to stretch, but have a backround image, this is useful.

  7. Avatar for Adam Kinney
    Adam Kinney January 14th, 2006

    Perfect, there's a good reason (differ only in Css) for me to use it in a futUre project, thanks :)

  8. Avatar for Jen
    Jen June 21st, 2006

    I did this myself actually (before finding your article) but when I ran the code through an XHTML validator, it didn't validate (apparently 'h1' cannot be inside an 'a' tag) Any ideas for alternatives to this?

  9. Avatar for Mike
    Mike June 22nd, 2006

    Same issue as above.. plus i don't want to use an <h1> tag.. so i use the <p> tag.

  10. Avatar for justin
    justin July 7th, 2006

    Hi I have a similar Q. I am tryin to link a background image to a webpage. my website is generatin random background image in a table cell so i want to link each indiviual image to different web pages....I cant make the whole table cell as hyperlink coz I want indiviual image to point at different webpages....
    I wud really appreciate if neone can help me over this

  11. Avatar for michael
    michael August 4th, 2006
  12. Avatar for Ben May
    Ben May September 28th, 2006

    Thanks so much man, this is EXACTLY what I've needed for ages!!!!!!!!!!! Cheers!

  13. Avatar for John Andrews
    John Andrews February 26th, 2007

    You really don't want to put that H1 in there. The h1 tag signals topical heirarchy information, and search engines use it to help interpret the semantic meaning of the page content. No big deal to not be helpful, except because you have an H1 hidden behind an image, it suggests you might be hiding a content signal behind an image because it doesn't actually match your user content. That's one way to spam the search engines. Google at least watches for it. This happened to TypePad when they had h1 tags behind the masthead logo image. Google sent warnings to people who had wordy titles in the hidden h1 tag, even when they were relevant.
    As an experienced SEO I am pretty sure the h1 gave Google a reason to impart spammy intent. It clearly doesn't belong.
    I like the post otherwise. Helpful for sure.

  14. Avatar for George Hayford
    George Hayford March 4th, 2007

    Would it be SEO friendly to take out the text e.g
    a href="/" title="Home"><h1>Title</h1></a

  15. Avatar for ross
    ross March 17th, 2007

    thing is absolute is not recommended on w3c...

  16. Avatar for furtographer
    furtographer July 31st, 2007

    I want the (h1) header and the subtitle to be visible and linked (real text). And I want the entire flexible-width header plus background image to be clickable, as well. It was simple to put the (div) inside the (a), until I found you can't put a block element (div) inside an inline element (a).
    So I guess I'm going to link both the (h1) and the (span class=subtitle), but with the (a) nested within each. And in the CSS make them Display:Block, and give them huge padding areas with Border:None, Text-Decoration:None, and Overflow:Visible. But I hope the stiff pixel dimensions will accommodate a user-font-upsize of 2 or 3 sizes. I don't want the header height to grow and show the inflexible background image.

  17. Avatar for jesse
    jesse September 1st, 2007

    Yay, neat trick. Thanks for sharing.

  18. Avatar for Ruby
    Ruby March 4th, 2008

    I think I've found an interesting solution that I haven't read about yet. I'm using a wordpress blog and didn't want to actually put an image tag in the .php files because I want the css document to do absolutely all the work when it comes to styling. Alistapart wrote an article indicating that display:none renders the title invisible to screen-readers. Hence, my search for another solution:
    here's the code for the header:

    <div id="header">
    <h1><?php bloginfo('name'); ?><br>
    <?php bloginfo('description'); ?>
    </div><!-- end div header -->

    the above code displays the blog title and blog description, depending on what the user inputs.
    in the stylesheet I coded the header div and the h1 a combo (though reasonably, I could have probably left the h1 tags out, but I wanted the importance of the header to remain paramount. My understanding is that h1 tags also indicate importance within the markup.

    #header {
    background: url(images/title.jpg) no-repeat;
    border: 2px solid blue;
    height: 75px;
    width: 509px;}

    #header h1 a {
    height: 75px;
    width: 509px;
    opacity: 0.01;
    position: absolute;
    text-align: center;}

    Interestingly, the inclusion of the 'position' tag seemed to ensure that the boundaries of the background image were entirely clickable. Before that inclusion, the text was clickable, but the empty space around it was not, no matter what size it got to. It doesn't matter what font size the text is, since the space is clickable, but it's invisible because of opacity. What I'm not sure about is how much opacity is supported in older browsers. I suspect it's unlikely. I tried to combine text-indent with negative margins with this solution, but it seems to conflict with text-align and the position. Your Mileage May Vary.

  19. Avatar for Peyo
    Peyo March 30th, 2008

    Hi all!, I was trying to use this tip, but It doesn't seem to work in IE6... could someone please confirm this?
    I can see that the tag is correctly positioned and sized through DebugBar, but the region isn't clickable. The text inside is clickable though.
    Thanks to all

  20. Avatar for Peyo
    Peyo March 30th, 2008

    OK, after some struggling with ie, I have figured out why it wasn't working, the problem was that there was an image and some text positioned in the same area than the (a) tag.
    Although the (a) had the highest z-index, IE was placing it in the bottom...

  21. Avatar for e devlet
    e devlet June 16th, 2008

    css background examples , Properties , Attribute - -

  22. Avatar for andysutils
    andysutils January 8th, 2009

    hahahaha, omg how ace are you. you are the absoloute God. you've just save my life.
    ive sweated blood sweat and tears trying to work out how to do this for weeks.
    thanks you very very much my friend

  23. Avatar for Markei
    Markei January 29th, 2009

    After using this technique, how do I then re-position the text links that were over the background - that got booted due to the block-level display? Is this possible? Will the text links still work sitting on top of a 'clickable background' if it's even possible to put them there??
    Thanks in advance for any help.

  24. Avatar for Anja
    Anja February 8th, 2009

    Whoa.. thanks a lot - I loved it, and it was nice to see that I had my topbanner to work... Really nice of you to share it with others :-) Best regards from Denmark :-)

  25. Avatar for David Andrew Wiebe
    David Andrew Wiebe April 6th, 2009

    Thanks, Phil! You saved my butt. :P

  26. Avatar for Mobila Dormitor
    Mobila Dormitor December 23rd, 2009

    Thank you so much. I have seen other examples, but this works excellent for me.

  27. Avatar for Doug Davis
    Doug Davis March 15th, 2010

    I still don't get it. If I want the clickable area to take me to a web page where do I put the url?

  28. Avatar for mark
    mark April 21st, 2010

    Thank you! Works like a charm.

  29. Avatar for kiruba
    kiruba July 14th, 2010

    Thanks a lot...God Bless You!!

  30. Avatar for Jim
    Jim July 19th, 2010

    Just what I needed! I float the pages so I used
    #header a
    width: 780px;
    Many thanks!

  31. Avatar for Jogny
    Jogny August 15th, 2010

    Don't use this! Very search engine UNfriendly!

  32. Avatar for Sam
    Sam September 22nd, 2010

    Thanks so much for sharing. Any idea on how to make it work on a Blackberry Browser??
    Many Thankxx

  33. Avatar for mira
    mira October 12th, 2010

    thank you. it works!

  34. Avatar for Steve
    Steve March 2nd, 2011

    Article is misleading! Anyone with basic knowledge can wrap href tags around some text in a div. Pretty easy.
    How about using a xhtml div element with a seperately coded css background image and making that image clickable/linkable?? Probably a job for javascript, eh?
    ps: "display: none;" does not work, it just hides the text and makes it unselectable.

  35. Avatar for roukie
    roukie May 20th, 2011

    The Clickable Background images using CSS works great. But i am not able to Save the Image using right click. When i right click the image, the save option is not visible. I know that including a background image in the css blocks us from saving the image using right click, but i want to find if there is a setting which i can use in the css which enables this option for me.

  36. Avatar for steph le plombier
    steph le plombier May 22nd, 2011

    sorry but it's not work for me on Firefox 4...

  37. Avatar for mandark
    mandark July 28th, 2011

    Why would you not just use the img tag in between the anchor tags, and also include the alt attribute for image tag which is searchable in the web.

  38. Avatar for Amir
    Amir December 2nd, 2011

    Thanks a lot for your good solution. This was what I need.

  39. Avatar for deano
    deano January 4th, 2013

    i'm glad it worked for you. it conflicted with the rest of the links in the header and when I made it into class it wouldn't anchor to the h1 tag, only to text when it wasn't invisible.

  40. Avatar for Rebecca
    Rebecca September 10th, 2014

    This was really helpful. I really like how it's all clean css. I needed to have several stylesheets for my mobile app with different image sizing.

  41. Avatar for Jewellery Monthly
    Jewellery Monthly December 4th, 2014

    Great tricks thanks