PDA

View Full Version : MENU on mouse over an Image



PET
Mar 7th, 2008, 10:02 PM
Hello,

I have a menu made from IMAGES. The images also have a RollOver effect.
On 2-3 images, I want to have a small drop down menu that will have some links.

I know the google is FULL of menus, but I just need this. NOOOoo need for "unlimited" sub-forums, flashy things, shadows and other crap. Just this.

When I put the cursor over an image, I want a small dropdown with links.

Any sugestions?

Thanks

Dan Schulz
Mar 7th, 2008, 10:36 PM
I'll do one better than that. Show me the images you're using (and the rollover states), and I'll not only make it for you, but also walk you through the process by writing a tutorial here on the thread that you and others can learn from. :)

PET
Mar 7th, 2008, 10:40 PM
www.sterlet.ro/nou/

This is the website and the menu is in the left.

Thanks

Dan Schulz
Mar 8th, 2008, 12:28 AM
Gotcha. Which menu items do you want the dropdown to appear on? (In other words, what content do you want in the dropdown menu items, and which menu items do you want to have the dropdown effect?)

PET
Mar 8th, 2008, 01:57 AM
Dosn't mather. Just put a dropdown on to images with some bogus links. I will modified after.

Thanks

rangana
Mar 8th, 2008, 04:41 AM
Maybe this links could keep you going ;)

http://dynamicdrive.com/dynamicindex1/blmmenu/index.htm
http://dynamicdrive.com/dynamicindex1/jimmenu/example2.htm
http://dynamicdrive.com/dynamicindex1/jsdomenu/index.htm

Dan Schulz
Mar 8th, 2008, 10:16 AM
Ok, here's a "quick and dirty" menu - note that it is NOT keyboard accessible (that requires some VERY advanced CSS and JavaScript to pull off), nor does the main menu play nice when the text is resized. I'll show you a much better (and far more accessible - unless you're a keyboard user that is since I need to get the permission of the author of a VERY handy JavaScript file to use the darn thing in my writeup) later on (I can't do it this weekend because I have several sites I need to re-code for others).

http://www.dan-schulz.com/for-others/pet/dropdown-menu/template.html

The directory is unlocked so you can grab the single image file that makes up the menu graphics. http://www.dan-schulz.com/for-others/pet/dropdown-menu/

The HTML for the menu is dead simple. A single unordered list with an ID of "menu" for the top level menu, which in turn contains links and in one case a nested unordered list.

The top-level menu items have a class (I could have used an ID but I figured you might want to reuse the class names later on) on them and contain an empty SPAN that I'll be using for the image substitution.

You'll notice that there's a lang and xml:lang attribute in the nested list items - you can safely ignore that. Since I set the lang and xml:lang attributes to "ro" (Romanian) in the HTML tag, I "switched" to English for those specific links. You'll want to remove them, and the English words, of course. Just make sure that you nest your lists as siblings of the links in the parent lists though when you add your other dropdown menus.

Anyway, on to the CSS.



#menu, #menu * {
margin: 0;
padding: 0;
}


The first thing I did was strip the margins and padding from the <ul id="menu"></ul> tags and everything inside them. If you're using a universal reset (like * {margin: 0; padding: 0;} for example) you can safely remove this since it'll be redundant.



#menu {
width: 180px;
}
#menu li {
float: left;
list-style: none;
position: relative;
}


The next thing I did was set a width on the menu, and then floated the list items (to squash an IE 6 bug), removed the bullets from the list items, and set their position to relative. The last property is going to become VERY important later on, since we'll be using absolute positioning to literally make the nested lists disappear (and then reappear when the link is hovered over). But I'll show you how that works when the time comes.



#menu li a {
background: #12688B;
color: #FFF;
display: block;
height: 27px;
line-height: 27px;
overflow: hidden;
padding: 0 0 0 15px;
position: relative;
text-align: center;
text-decoration: none;
text-transform: lowercase;
width: 165px;
}

#menu li a:hover {
background: #3AAAF0;
color: #FFF;
}


This style rule covers the links in the lists (though some of them will be overridden later on). I set the background color and text color to mimic the background image (just in case images aren't enabled, have been turned off, stripped by a firewall, whatever). I also set the display state to "block" so that the link will occupy every single last centimeter of space in the list item. I then set the height and line height to be the same so that there's even spacing (without the need for padding) between the links.

The overflow was set to "hidden" to keep the text inside the link in case the user resizes the page too much, while the position was set to relative so that the empty SPAN inside each link will have a point of reference later on. The width was set to 165px (even though the links are 180px), with the final 15px being handled by the left padding (for the 180px width). The remaining styles were set to mimic the image in case it can't be shown.

The hover state was used to change the background color, nothing else (the link text color remained the same).



#menu li a, #menu li a span {
height: 27px;
}


The links and the empty spans share a common height (though not much else), so I decided to save a few bytes by declaring them all at once. The next part though is where the magic starts. Those empty spans are being used as containers which will hold a single image - your menu graphic. Rather than using 20 different images (which would require 20 different HTTP requests - one for each graphic requested by the server), I combined them all into a single file. So rather than 20 different requests for 17KB, I cut all that down to 12KB (yeah, my one image file is smaller than your 20 files) and one call to the server. Dialup users will REALLY appreciate this as they'll be able to use the menu while the image is downloading (which at 12K will take about 3 seconds at 56k dialup) and also won't have to wait for the hover states to download since we'll be changing the background position to "slide" the hover state into place. :)



#menu li a span {
background: url("images/menubg.png") no-repeat;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
width: 180px;
}


And this puts the image into place. The background property calls the image (note with this technique your image cannot be transparent) and just to be on the safe side (even though it's not needed) the image has been set not to repeat. The cursor was set to "pointer" to kick Internet Explorer in the duff (it was refusing to show the hand/pointer cursor) while the width was set to 180px (had I not used padding on the links, I could have declared that with the height earlier as well, but oh well). The real trick though is the use of absolute positioning here. Set the position to absolute, and the top/left positions to 0 and the span literally snaps into place - occupying EVERY PIXEL inside the link.



#menu .home span {
background-position: 0 0;
}

#menu .home:hover span {
background-position: -180px 0;
}

#menu .despre-noi span {
background-position: 0 -27px;
}

#menu .despre-noi:hover span {
background-position: -180px -27px;
}

#menu .portofoliu span {
background-position: 0 -54px;
}

#menu .portofoliu:hover span {
background-position: -180px -54px;
}

#menu .servicii-oferite span {
background-position: 0 -81px;
}

#menu .servicii-oferite:hover span {
background-position: -180px -81px;
}

#menu .ramuri-ale-aevaculturii span {
background-position: 0 -108px;
}

#menu .ramuri-ale-aevaculturii:hover span {
background-position: -180px -108px;
}

#menu .sisteme-de-acvacultura span {
background-position: 0 -135px;
}

#menu .sisteme-de-acvacultura:hover span {
background-position: -180px -135px;
}

#menu .pescuit-sportiv span {
background-position: 0 -162px;
}

#menu .pescuit-sportiv:hover span {
background-position: -180px -162px;
}

#menu .parteneri span {
background-position: 0 -189px;
}

#menu .parteneri:hover span {
background-position: -180px -189px;
}

#menu .evenimente-noutavti span {
background-position: 0 -216px;
}

#menu .evenimente-noutavti:hover span {
background-position: -180px -216px;
}

#menu .contact span {
background-position: 0 -243px;
}

#menu .contact:hover span {
background-position: -180px -243px;
}


Here I just set the background position for each menu item. By referencing the main list (#menu) and then the link with the class and the span, I can set the position to wherever I want it. In this case, I set the X axis to 0 while setting the Y axis to equal the top position of each menu "state" in the image (just add 27 pixels in this case). For the hover states, I copied the same styles, added :hover to the classnames and then slid the X axis back 180px to reveal the hover state for that particular part of the image.



#menu li:hover ul {
left: 180px;
}

#menu li ul {
min-height: 1&#37;;
position: absolute;
top: 0;
left: -999em;
width: auto;
}


Now, for the dropdown part, I told the list item that when it's hovered over, to set the position of the nested list to 180px (left). The reason why I did this is because the nested list had its position set to absolute as well. The nested lists position (after being set to absolute) was set to 0 (top) and -999em (left), which pushes it off the screen. I could have used display: block and display: none respectively, but that can interfere with screen readers (yeah, I know, I'm being hypocritical here - be mindful of screen readers, but ignore keyboard users, sorry but there's only so much I can do in a single post, especially given copyright concerns). I also added min-height: 1% on the nested list as well to force IE7 to show the dropdown list (it's an issue called hasLayout). The width was set to auto because I wasn't thinking and figured that you might want a placeholder in case you need a wider width.



#menu ul li {
float: none;
list-style: none;
}

#menu ul li a {
background: #12688B;
color: #FFF;
height: auto;
padding: 0 0 0 15px;
text-align: left;
text-transform: none;
}

#menu ul li a:hover {
background: #3AAAF0;
color: #FFF;
}


I'm sure you should be able to figure the rest of this out, but I'll note that I removed the float on the nested list items (so they can display normally) and preserved the 15px of left padding on the links as well. (I forgot to mention this, but when you see a shorthand property value like 0 0 0 15 that's referencing the top, right, bottom, and left values respectively - or TRouBLe - if that helps you remember the order.)

Anyway, it's past 3am here and I need to head to bed, so if you have any questions, feel free to ask me and I'll do my best to answer them when I wake up (if nobody else has by then of course). I will note that the dropdown effect does not work in IE 6 since that browser doesn't support :hover on anything but links. Fortunately there's a great way around that, but it does require either adding or editing a .htaccess file on your server:
http://www.xs4all.nl/~peterned/csshover.html

abduraooft
Mar 8th, 2008, 12:08 PM
Anyway, it's past 3am here and I need to head to bed,..........
........but it does require either adding or editing a .htaccess file on your server:
Hope you meant csshover.htc file.

PET
Mar 8th, 2008, 07:10 PM
Thanks Dan. Useful post, however, you said it's not working for IE6. Well this is pretty important.

effpeetee
Mar 8th, 2008, 07:23 PM
http://css.maxdesign.com.au/listutorial/index.htm

This may be worth a visit. Admission FREE.

Frank

Dan Schulz
Mar 8th, 2008, 07:51 PM
Hope you meant csshover.htc file.

No, I meant the .htaccess file. You have to add the proper MIME type to the HTTP headers via the .htaccess file or else the csshoer.htc file will not work (since IE 6 in XP Service Pack 2 requires the proper MIME type in order to work).


Thanks Dan. Useful post, however, you said it's not working for IE6. Well this is pretty important.

As is it's not working. Adding the csshover.htc file (and adding the MIME type to the server) will fix that problem - as well as let you use :hover on any element in your page, not just the menu. :cool: