First time visitor? The tutorials start here.

CSS Link Hover Effects (aka Rollovers)

You thought this next tutorial was going to deal with lists, didn’t you? Well, what we really did at the end of that last tutorial on styling lists was style the links within that list, which really has nothing to do with the list itself. In this tutorial, I’ll explain how that worked, and then show you how to do image rollovers without javascript. But first, here’s what that list looked like once we put the CSS in…

And here is the CSS we used for that:

ul li a { 
	display: block;
	border-left: 10px solid #ccc;
	padding: 0 0.25em;
	text-decoration: none;
}
ul li a:hover {
	border-color: #f00;
	background: #f3f3f3;
}

Remember how we targeted <li> tags within <ul> tags but not within <ol> tags? If you don’t, go back to that last page for a refresher. Specifically, it’s the paragraph that begins with, “On a side note,” under the heading of Bye Bye Bullets.

In the above CSS, we are going into <ul> (unordered list) tags, finding the <li> (list item) tags that are nested inside them (<ul><li>…</li></ul>), then going inside those tags to find and style the <a> (anchor link) tags (<ul><li><a…>…</a></li></ul>). The first block (ul li a) deals with all of the anchor links within <ul><li>…</li></ul>, and the second block (ul li a:hover) deals with those same links, but only when they are hovered on (thus, the :hover in a:hover).

Block Level vs. Inline Elements

To explain the first line of that CSS, I need to explain block-level elements and inline elements.

A block-level element will start on its own line by default. These block-level elements include paragraphs (<p>), divs (<div>), lists (<ul> or <ol> with <li>s inside), and forms (<form>, which we haven’t yet covered).

An inline element will continue within the flow of its surrounding content, such as links (<a>), spans (<span>), emphasis (<em>), strong emphasis (<strong>), and inline frames (<iframe>, which we haven’t yet covered).

You can change the inline vs block-level default behavior of any of these elements in your CSS. To change a block-level element to inline, you would use display: inline; and to change inline to block-level, you would use display: block;

Here, since anchor links are inline elements and we want to change them to block-level, we defined them as display: block;

Assuming you still have your practice files open or know how to do that by now, go ahead and take display: block; out of the CSS for ul li a and put border-bottom: 1px solid #ccc; in its place, and see what difference that makes. This is why we need to set it to block for what we’re doing here. Now go ahead and put display: block; back in, but leave that border-bottom, save, refresh, hover, and see the difference.

I will include the display attribute in my list of CSS attributes eventually (which also includes “none” as a possible value), but wanted to cover inline vs block-level here as well.

More on link hover effects

Here’s that CSS again, with the bottom border included:

ul li a { 
	display: block;
	border-bottom: 1px solid #ccc;
	border-left: 10px solid #ccc;
	padding: 0 0.25em;
	text-decoration: none;
}
ul li a:hover {
	border-color: #f00;
	background: #f3f3f3;
}

As you can see from the ul li a definitions, the left and bottom borders’ width (10px or 1px), style (solid), and color (#ccc, same as #cccccc) are all defined there.

For ul li a:hover there is no need to redefine anything that doesn’t change when the link is hovered on, such as border width and style, but we did redefine border-color because that attribute does change when the links are hovered on.

We also don’t want the padding to change when a link is hovered on (boy, would that be a mess!), so we defined that in ul li a without changing it in ul li a:hover, and there was no need to repeat it since it’s still an anchor link.

The background color of those links does change when they’re hovered on, because we defined a new background color there.

In preparation for this next part, change this:

ul li a { 
	display: block;
	border-bottom: 1px solid #ccc;
	border-left: 10px solid #ccc;
	padding: 0 0.25em;
	text-decoration: none;
}
ul li a:hover {
	border-color: #f00;
	background: #f3f3f3;
}

to this:

ul li a { 
	display: block;
	height:  30px;
	line-height: 30px;
	vertical-align: middle;
	text-align: center;
	border: 1px solid #ccc;
	text-decoration: none;
}
ul li a:hover {
	border-color: #f00;
	background: #fff;
}

I’ve set the height and line-height to the same thing, so when we apply vertical-align: middle; to it, it vertically aligns the word within that line-height (vertical-align in this case isn’t necessary in all browsers, but it’s best to be sure for all browsers). I will add vertical-align and line-height to the CSS attributes list eventually; if you’re reading this a few weeks after I’ve made this post, it might already be there.

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 (9)

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 πŸ˜€

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.”

liamJanuary 31st, 2011 at 5:45 am

Hi, I hope you can answer what I’m sure is a simple question.

In my css style sheet I’ve:

a:link {
color: #FF0033;
text-decoration: underline;
font-weight: normal;
}
a:visited {
color: #0000FF;
text-decoration: underline;
font-weight: bold;
}
a:hover {
color: #0099FF;
padding-bottom: 5px;
font-weight: bold;
text-decoration: underline;
}
a:active {
color: #FF0033;
font-weight: bold;
}

Being new to this and teaching myself through help as you give, when I play around with the a:link properties/values as in color or weight, save and refresh – there’s no change at all to my links. Why is this?

The links do change when the other properties and values are changed and as setup above, they work as they should. But the a:link seems totally useless.

So why does nothing change & should the a:link have no properties or values when the others do?

BTW, my htm file has no link code.

Thank you πŸ™‚

liamJanuary 31st, 2011 at 5:48 am

Sorry, my BTW may seem confusing (duh).

What I mean is that I only use the style sheet to define the style, the htm file has no styles “inline or embedded”.

LesaJanuary 31st, 2011 at 4:12 pm

Hi Liam,

Are you absolutely certain there are links on that page that you haven’t visited yet? To make sure, try adding a link to a fake location. If this doesn’t solve your problem, feel free to post a link to the page in question. If you’d rather not, I can send you an email and you can send me a link in a reply. πŸ™‚

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.