Basically, I'll be showing you how to create a sliding highlight, like this example or the one on the navigation of my personal site. In either one, hover over the links to see the animation. Neat, huh? More interesting than just making the links change color or become underlined when you hover over them, and not too difficult to implement (or at least, it shouldn't be once you've gone through this tutorial).
What we'll be working with
We'll be creating this cool little sliding highlight with a combination of HTML, CSS, and jQuery.
- HTML will provide the structure.
- CSS will provide the style.
- jQuery will provide the animation in response to the user's actions.
Let's get started
I'll be showing you how to duplicate this example, and explaining how and why it's done along the way. First, we need to create the basic HTML structure. This bit of code goes in the BODY tag:
<div id="navigation">It's important that the ID attribute of the DIV tag be defined. The A tags are the links to the pages - on a real site, they'd have the address of the actual page in their HREF attributes, not just "#". Having the CLASS attribute of the link for the current page defined is also important.
<a href="#" class="current">Current Page</a>
<a href="#">Another Page</a>
<a href="#">Yet Another Page</a>
</div>
Next, we'll define some basic styling for this set of links. This is the CSS for the page, which I put in the HEAD tag for convenience:
<style type="text/css">If you're shaky on CSS syntax, take a look at the tutorial at w3schools.com. Here are the important parts of the first two rules above, which apply to the DIV with the ID attribute of "navigation" and the A tags it contains, respectively:
#navigation {
display: block;
border-bottom: 3px solid black;
position: relative;
}
#navigation a {
margin: 0 20px;
padding: 0;
text-decoration: none;
color: black;
position: relative;
}
#highlight {
display: block;
position: absolute;
bottom: -3px;
height: inherit;
border-bottom: 3px solid red;
}
</style>
#navigation
- border-bottom - This creates the black line under the links.
- position - This is the really important one; I'll explain why later.
#navigation a
- margin - This spaces the links out. The shorthand syntax "0 20px" means that the links will not create any space above or below them, but will create 20 pixels of space to the right and left. This means that there will be a 40-pixel gap between links that are next to each other.
- text-decoration - This gets rid of the default underline on the links. We don't need it for this example, because we have the black underline on the box.
- color - This changes the text color of the links from the default blue to black.
The "highlight" element is going to be added via jQuery. I did it this way so that if JavaScript is disabled in the user's browser, they won't see an ugly, randomly positioned red underline that doesn't do anything. Instead, they'll just see the links with the single black underline.
First of all, you'll need to link the jQuery library to the page. See my previous post about jQuery slideshows to see the details of this. The end result should be a jQuery file in your root folder and this line in your HEAD tag, just after the STYLE tag:
<script type="text/javascript" src="jquery-1.6.4.min.js"></script>Alternatively, you could use this line, which will create a link to an online jQuery library hosted by Google:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>That way, you won't have to download the jQuery library.
Next, create the basic framework for a jQuery script by adding this to your HEAD tag:
<script type="text/javascript">All the scripts that come later in this post will be placed in the blank space in the middle of that code, between the curly braces. Here's the first script to add:
$(document).ready(function(){
});
</script>
$("#navigation").prepend('<span id="highlight"></span>');This basically means that the script will find the element with the ID "navigation" and add the code "<span id="highlight"></span>" to the beginning of it, before anything else contained in the code. The result of this would be the following HTML structure:
<div id="navigation">In the script, it's important to use single quotes in the parentheses after "prepend" instead of double quotes.
<span id="highlight"></span>
<a href="#" class="current">Current Page</a>
<a href="#">Another Page</a>
<a href="#">Yet Another Page</a>
</div>
Now we have our "highlight" element, and the styling already defined above can come into effect.
#highlight
- display - This makes the page pay attention to the width and height of this element.
- height - This will make "highlight" the same height as its container, "navigation".
- border-bottom - This creates the red underline.
- position - This is crucial. Setting this to "absolute" means that the element will be positioned using coordinates based on the dimensions of its containing element, the DIV with the ID "navigation". This is why we set the "position" property of "navigation" to "relative" earlier, so that it could act as the position reference for this element.
- bottom - This says to put the bottom of "highlight" 3 pixels below the bottom of "navigation", so their bottom borders should overlap perfectly.
$("#highlight").css({Basically, this finds out the width of the link with the CLASS attribute "current" and how far its left edge is from the left edge of "navigation". In this case, the 20-pixel left margin of the A tag is included in calculating the position. The script takes these figures and positions "highlight" to be 15 pixels to the right of the left edge of "current" (that is, 5 pixels to the left of the visible left edge of the text), and to make it 10 pixels wider than "current". The result is a red underline that is slightly wider than the "current" link and centered underneath it.
left: $(".current").position().left+15,
width: $(".current").width()+10
});
Now we get to the animation. jQuery makes this much easier than normal JavaScript, but it's still a bit tricky. Here is the script:
$("#navigation a").hover(Not exactly simple, is it? Let's break it down. First, look at the selector in the first line, "#navigation a", and the event, "hover". That means this function will be triggered when the user hovers over an A tag contained in the DIV with the ID "navigation".
function(){
$("#highlight").clearQueue();
$("#highlight").animate({
left: $(this).position().left+15,
width: $(this).width()+10
});
},
function(){
$("#highlight").delay(250);
$("#highlight").animate({
left: $(".current").position().left+15,
width: $(".current").width()+10
});
}
);
Second, note that there are two functions inside, with a comma separating them. The first is triggered when the mouse moves onto the element, and the second when the mouse moves off of the element.
The first function, triggered when the user mouses over the link, has two parts. First, it clears the animation queue attached to the "highlight" element. If we didn't do this, and the user moused over multiple links in quick succession, the highlight would move to the first link moused over, then back to its position under the current page link, then to the second link moused over, then back, then to the third...you get the idea. The animations would line up and be executed one after the other, trailing behind the user's actual mouse movements and becoming very confusing and annoying.
The second part of the first function, you should notice, looks very similar to the code we used to align the highlight to the "current" link. The only differences are that this says "animate", instead of "css", and that the code refers to "this" instead of ".current". The selector "this" just refers to the element that triggered the event - in this case, the script will get the width and horizontal position of the link that has been hovered over.
The second function, triggered when the mouse moves off the link, is almost identical to the first, though you should note that it refers to ".current" again, meaning it moves the highlight back to the link for the current page. The difference is that, instead of cancelling the animation queue, this function calls for a delay of 250 milliseconds (a quarter of a second). The "delay" action allows you to delay the execution of any queued animations for the specified length of time. In this case, the script waits a quarter-second before returning the highlight to its default position. The reason for this is to allow the cursor to move over the gap between one link and the next - otherwise, the highlight would spring back to its default position between every moused-over link, instead of transitioning smoothly from one to the next.
If you've followed my instructions carefully, you should now have something resembling the example. Hopefully, you also gained some understanding of how these bits of code work, and will be able to apply your new knowledge to different situations. If there's anything you would like clarification on, or any other visual tricks you'd like me to demonstrate, let me know in the comments.
The sliding highlight is cool. I want to use that on a site. I like the way you have the Read More link. It allows people to choose to read more or to move to another post. I would suggest loading linked pages in a new window so that it doesn't appear you're taking them to a new site.
ReplyDelete