This is as much informative as it is an archive so that I will remember how to create this again. This will make a fancy navigation bar with buttons that will transform slowly when the mouse is hovering over them. It creates a neat effect that button is being pressed and this could be extended so that when you click it transforms the button again making it look like it is being pushed into the screen. As opposed to some other navigation menus that require a new image be made for each menu item (the text being part of the image) this navigation bar will use a normal anchor with text node for the link text. Here is a live example of the navigation bar.
The only pre-requisite for this to work is the jQuery javascript framework. The only thing used from jQuery is the hover event, because it was easier and faster than writing my own hover handler for javascript. jQuery’s hover event mimics the :hover CSS attribute for any element. Actually, I also use the animate function which slowly increases/decreases the opacity of the divs.
The first thing to do is create the (x)html to hold the menu items. To be semantically accurate an unordered list will be used to hold the list of navigation menu items. Each list item will hold two DIV elements. One will be the button pressed one will be the button unpressed. Each div contains an anchor that the user will actually be clicking. This will be necessary later on.
Here is the markup for the navigation; the div around the list is unneeded, but it separates the menu from the header of my page. As you can see there are three entries for the menu: Home, About, Contact.
<div id="navigation"> <ul id="navMenu"> <li><div class="push"><a href="#">Home</a></div><div><a href="#">Home</a></div></li> <li><div class="push"><a href="#">About</a></div><div><a href="#">About</a></div></li> <li><div class="push"><a href="#">Contact</a></div><div><a href="#">Contact</a></div></li> </ul> </div>
Next is creating the images to make this look nice. I used just a vertical gradient from dark grey to lighter grey and the same gradient backwards for the pressed button. It also looks nice if you use a flat colour thats in the middle for the pressed button. Here is the background for unpressed buttons and the entire navigation bar:
Navigation Background
and here is the image for the pressed button:
Navigation Button Pressed
Ideally these would be 1 pixel wide so they take up little space, but it would be harder to show in this tutorial.
The Navigation Background image will be the background for the unordered list, the button pressed image will be the background for the first div in the list item. Initially the first div will be completely transparent; when the mouse hovers over it will become opaque and will show up in front (due to a higher z-index.
The CSS tricks to ordering the elements on the page is right here:
/* Take out the list style and give our background */
#navigation ul{
list-style-type:none;
background: url(../images/nav-button.png) repeat-x scroll top left;
height:30px;
margin:0 -10px; /* Just making the UL go completely across my container div (has padding of 10)*/
padding:0;
}
/* Making the list a row of line items*/
#navigation ul li{
position:relative;
float:left;
margin:0;
padding:0;
text-align:center;
}
/* Style the link */
#navigation ul li div a{
display:block;
width:125px; /* Anchor completely covers list item */
height:30px;
padding-top:5px
text-decoration:none;
color:white;
font-weight:bold;
opacity:1;
}
#navigation ul li div.push{
position:absolute; /* Will completely cover the list item and li content */
top:0;
width:100%;
height:100%;
background: url(../images/nav-button-push.png) no-repeat scroll top left;
opacity:0; /* Initially transparent */
}
As you can see the background images are set up exactly how I’ve already explained. The div for the pushed button background is positioned using absolute so that it will be taken out of the normal flow and sit above the normal div. Even though it is over top it will only be seen when the opacity is cranked up to 1. This is why the text is needed twice. When the opacity is cranked up on hover it will cover the original text and background image. To position the pushed div properly the line item element needs to be position:relative so that the pushed div will be relative to the line item and not the page.
The last piece to the puzzle is the Javascript to make the animation. It’s an easy few lines.
$(function(){
$('#navigation ul li div.push').hover(
function(){
$(this).stop().animate({opacity: 1},'slow');
},
function(){
$(this).stop().animate({opacity: 0},'slow');
}
);
});
The missing jQuery include needs to be added to the page as well, but I’m sure you can handle that.
Putting this all together gives a very snazzy navigation menu that does not require an image be made for each entry. All you need is the gradient, but these could even be flat colours. I’m working on creating pure CSS gradients as backgrounds, but that’s a whole new story.