Print this page

Image replacement for menu

this article brought to you by tsw

So your client wants menu with images and it cant be solved with background images and text on top. Though luck. There is a solution though which doesn't destroy all your accessability

We'll use image replacement technique to have accessability links as text and page id number for css id and have css change the text to a image

First we need image which holds all the links and their hover state:

image containing all links and their hover states

All links have been created in one image inlucding their hover state, this removes flickering as whole image is loaded in one GET (Images full height is 200px and width 500px. First link width is 100px and height 50px)

Now we need indication in menu for the links so we edit menumanager template to inlude id for each menu item. Add following code in the template for each li tag that will be replaced with image

<li id="i{$node->id}">

Now menu has id="i1" if page ID is 1 and we can use that to map our image with the menu, our test html looks like this

<ul id="nav">
  <li id="i1"><a href="#">First</a></li>
  <li id="i2"><a href="#">Second</a></li>
  <li id="i3"><a href="#">Third</a></li>
  <li id="i4"><a href="#">Last</a></li>
</ul>

and it renders as

Well need some css to place links according to the image links

Image for the ul and some height and width properties

ul#nav_styled {
width: 500px;
height: 50px;
margin:0;
padding:0;
background: url('image_replacement_menu.png');
position:relative;
}

We want li as block and to be as tall as image

ul#nav_styled li {
display:block;
height:50px;
margin: 0;
padding: 0;
list-style: none;
position: absolute;
top: 0;
}

a should also be block and 50px tall

ul#nav_styled li a {
display:block;
height:50px;
}

This is the boring part, every link has to be positioned according to the image

li#i1 {
left: 0px;
width: 100px;
}

li#i2 {
left: 100px;
width: 150px;
}

li#i3 {
left: 250px;
width: 150px;
}

li#i4 {
left: 400px;
width: 100px;
}

 

Now we have basic horisontal menu with our image as background and links forced to right positions (try hovering the links they will change background color)

Great, now we need hover state images on the links. We have already positioned all the links so we just give them a bg according to the position and lose the text links

#i1 a:hover {
background: transparent url(image_replacement_menu.png) 0 -50px no-repeat;
}
#i2 a:hover {
background: transparent url(image_replacement_menu.png) -100px -50px no-repeat;
}
#i3 a:hover {
background: transparent url(image_replacement_menu.png) -250px -50px no-repeat;
}
#i4 a:hover {
background: transparent url(image_replacement_menu.png) -400px -50px no-repeat;
}

and for hiding the text

ul#nav li a {
text-indent:-9000px; background-color:transparent; }

So there you have it, images as links and still accessible from text browsers and most screenreaders. only problem is that you must create a new image if you want more links

appropiate glory goes to Mike Rundle and Dave Shea thanks


  • rayH - July 24, 2008, 9:36 am
    Thanks for this = I must admit that this type of menu does seemcomplicated but again your no nonsense style explains it well.

  • rogus - August 2, 2008, 10:01 am
    mate - is in it more accurate with $node->alias +"_menu"

    then it seems more descriptive for css
    as sometimes you do get errors for instance while changing the id's ...

    labels (alias) seems more definite and will hardly change during the development right?
  • risk - October 7, 2008, 9:45 am
    Hey, thanks for this great script. :)
    That is what I was looking for.

    The only thing is, the IE6 seems to have problems with this script. Here's the screenshot of ie6 and other browsers:
    http://www.da-risk.de/prelive/menu_ie6_problem.jpg

    Another questions is:
    Is it possible to set the hover state of the menu image as default at current active page - e.g. the hover state of the &quot;home&quot; image as default at the &quot;home&quot; page?
    I think it would be more efficient and crealy arranged for the visitors.

    Thanks in advance! :)
    risk
  • risk - October 7, 2008, 1:08 pm
    Hey, it's me again! :)

    The hover/active state thing is solved.
    That's my first CMSms project, so it took a little bit more time.

    For other greenhorns (like me): :)
    Just set the &quot;.menuactive&quot; style to the hover rules in your menu css. that's it.

    I'd still be very thankful for every tip regarding the IE6 problem.

    Regards from Germany!
    risk
  • Adam - October 7, 2008, 3:28 pm
    I don't think IE6 likes the "hover" tag in css. In past experience (in web design in general, not necessarily CMSMS) I've had to use javascript to get that effect in IE.
  • risk - October 9, 2008, 1:01 pm
    Hi Adam,

    Can you tell me which javascript you've used to get that effect in IE?
    I'd be very glad and thankful if we could fix this problem.

    Thanks in advance! :)

    Regards
    risk
  • risk - October 10, 2008, 8:31 am
    It's me again - I hope for the last time. ;)

    The IE6 problem was triggered by a pngFix javascript.

    Regards
    risk
  • rogus - November 18, 2008, 4:48 am
    why have you deleted all the comments?
    Great man....
  • mrks - November 22, 2008, 3:18 pm
    just for understanding:

    i need no menu-template anymore?

    thanks!
  • Lone - December 10, 2008, 9:58 am
    Hi - this is a great example, thanks.

    One thing, though, the ul should be named consistently either ul#nav or ul#nav_styled in both html and css. Otherwise it will not work.

    kind regards, Lone
  • Sabaqahmad - July 27, 2009, 6:03 am
    very excellent
Add A Comment

Add A Comment

This is a captcha-picture. It is used to prevent mass-access by robots. (see: www.captcha.net)
Code in the picture (*):
Your Name (*):
Comment (*):