First time visitor? The tutorials start here.

CSS Link Hover Effects (aka Rollovers)

Image Rollovers

Who needs javascript when CSS can do the exact same thing, even on browsers that have javascript disabled? Not us! :)

If you downloaded the practice files before the date on this post, you will need to save this image to your computer, putting it in the “images” folder of your practice files:

button

Believe it or not, this is one button. Once we’ve added the CSS, the links will have the top half of the image behind them by default, and the bottom half of the image when the links are hovered on.

Demo:

First, I want you to get rid of the borders around your lists. To do that, take all border definitions out of this line of CSS:

ul, ol { border: 1px solid #999; margin: 1em 0; padding-left: 0; }

If you don’t know what that line is supposed to say when you’re done, highlight the solution below by clicking and dragging your mouse across it (this won’t make sense if you are reading this from a printed page):

ul, ol { margin: 1em 0; padding-left: 0; }

Now, remove the borders from the anchor links that reside in the list items that reside in the unordered list.

If you need to, highlight the hidden solution below:

ul li a {
	display: block;
	height:  30px;
	line-height: 30px;
	vertical-align: middle;
	text-align: center;
	text-decoration: none;
}

Now your first list in the sidebar should consist of 5 links, horizontally centered within the sidebar, without borders, and with about a line-height of space between each link. Are you ready for the fun part?

button

The background image you’re about to use is 200px wide by 60px tall, and you only want the top or bottom half of it (30px) to show up at any given time . The sidebar itself is 200px wide and the list takes up all of its available width, so that part is taken care of.

I also had you set the links to 30px tall (adding line-height of 30px so the words are vertically centered within the “block”), so we are all set on height as well. So, all that’s left to do now is add the background image.

In your ul li a definitions, add this:

background: #000 url(../images/button1.png) center top no-repeat;

If you need help, highlight the hidden solution:

ul li a {
	display: block;
	height:  30px;
	line-height: 30px;
	vertical-align: middle;
	text-align: center;
	text-decoration: none;
	background: #000 url(../images/button1.png) center top no-repeat;
}

If you don’t know how that new line of CSS works, you can read about the CSS “background” attribute here, then click the “back” button on your browser to return to this page.

Notice that we used a black background color along with the image. Here are a few good reasons for doing this:

  1. If someone on dialup has to wait for the images to load, we want them to be able to read the links in the meantime. It also makes for a nicer transition between no-images and images if their connection is slow enough to see that transition.
  2. Some people might disable images completely in their browser settings.
  3. If your images are stored on one website and you’re displaying them elsewhere, the image host could go down and you still want people to be able to read the text.

Save your CSS, then refresh the page in your browser. The words are still centered in the sidebar, but with these backgrounds, it would look much better to center them within the black area of the background image.

To do this, add 22px of padding to the left side of those same links. Just before text-align should be good, since we’re working with horizontal alignment. Your CSS should now look something like this:

ul li a {
	display: block;
	height:  30px;
	line-height: 30px;
	vertical-align: middle;
	padding-left: 22px;
	text-align: center;
	text-decoration: none;
	background: #000 url(../images/button1.png) center top no-repeat;
}

Are you with me so far? If not, feel free to leave a comment at the end of this tutorial and I will have an answer for you within a day, or sometimes even in minutes, depending on whether I am at my computer at the time. :)

After you’ve saved your last edit in the CSS, save that file and refresh the page. The links now have a nice background image behind them and the words are centered within the black area of that background image. But wait… Hover on one of the links. The background turns all white, and here’s why…

Currently, we have this for its hover state:

ul li a:hover {
	background-position: center bottom;
	background: #fff;
}

border-color doesn’t do anything anymore since we took the borders out of the links. Therefore, you can remove that line. We also don’t want the white background color, so you can remove that other line, as well. Now we’re left with no definitions for the hover state of those links! Oh, whatever will we do now?

After removing those two lines from your CSS, save it, then refresh your browser and hover on those links. What happens now?

button

This background image is still there, and still showing the top of the image. Also, the text seems to disappear. Why?

Hover on the links in the ordered list beneath the pretty links to see why. Yes, that’s right, because the links turn black when they’re hovered on. So now what we want to do is:

  1. Reposition that background image so it shows the bottom half when it’s hovered on, and
  2. Change the link color to something that’s visible on a black background.

For the first one, we use background-position: center bottom; Remember, we don’t have to actually add the image, because it’s already there. We only need to reposition it, which is what we’re doing here.

For the second one, we use the color attribute (click on that link if you don’t know how to use it). Let’s define those links to be white (#ffffff or #fff, they both do the same thing) when they’re hovered on.

See if you can do this on your own first, then highlight the hidden solution below:

ul li a:hover {
	background-position: center bottom;
	color: #fff;
}

Save your changes, refresh the page, and have fun hovering on those links. :)

Notes:

We could have used two separate background images: One for a link’s regular state and one for its hover state. However, if you’re familiar with javascript rollovers, then you should be familiar with “pre-loading” images.

Images that will be used for “rollovers” are often pre-loaded to prevent the image from disappearing before the new one can load, which happens a lot to people who access the internet through dialup.

I remember my dialup days, and used to be annoyed as heck having to wait for those darned rollovers every time I would hover on a link. But by combining the two images into one and only showing half at a time, the image is already loaded before it’s hovered on.

If you would like to have a third effect when a link is actually clicked on, you can put three images into one and define the clicked, or active, state as a:active (or in the case of this particular exercise, ul li a:active). For the middle part of the image, its background-position would simply be center.

Next: More on floats, including how to quickly and easily move that sidebar to the left side of the page. After that, we’ll make that practice page look a bit nicer.

This post has multiple pages. Go to page: 1 2

If you found this article useful, please spread the word:
Stumble it! Digg! Tweet it!



Comments (6)

JeffApril 12th, 2009 at 9:30 pm

There is some missing information on this page.

The line starting with “border-color doesn’t do anything …” is apparently broken in IE, and the proposed solution:

ul li a:hover {
border-color: #f00;
background: #fff;
}

does not reposition the image.

JeffApril 12th, 2009 at 9:55 pm

Ah… discovered the problem.

background-position: center bottom; ((( missing from the proposed solution )))
border-color: #f00;
color: #fff; ((( instead of background: #fff; which overwrites the image )))

LesaApril 13th, 2009 at 3:03 am

Hi Jeff,

You’re absolutely right about the background-position and color, but border-color isn’t needed. Somehow I managed to explain that correctly, but must have had the old CSS in my clipboard when I tried to paste the new version in.

Thanks for helping me fix that. :)

JeffApril 13th, 2009 at 3:59 am

Haha I was having a devil of a time getting it to work :D

LesaApril 13th, 2009 at 4:01 am

It turned out to be a good test, then. Excellent job! :)

LesaJune 21st, 2009 at 12:38 pm

Thanks to Cameron Chapman for including this tutorial in her article, “7 Rich & Creative User Interfaces and How to Create Your Own.”

Questions or comments?

Please log in to post a comment. Sorry, but it prevents this from happening. If you're not registered yet, you can register here.