Snazzy Hover Effects Using CSS

Snazzy Hover Effects Using CSS

With all these CSS3 effects and tutorials popping up every day that show all the new and wonderful things we can make happen, we sometimes forget about poor little old CSS2.1 and the great potential it still has.

With very good browser support, we can do lots of cool things that we know will work in all major browsers.

In this tutorial, I will be going over creating flexible advanced hover techniques using CSS2.1 properties.

Advanced hover states are quite simple

When I first started learning CSS, the :hover pseudo-element was no more than a way to remove the underline on a text link.

Since then, through experimentation, I have learnt that it is so much more powerful and it can create some really cool effects when used in conjunction with other CSS properties.

One of these effects is creating caption text to appear over the top of images, creating some nice visual feedback for the user and giving them some information about the image they’ve moused over or focused on.

The astute reader will see that this technique has great potential outside of what we discuss here, such as showing CSS tool tips when hovering over a hyperlink.

We’ll be using these key CSS property, pseudo-classes, and pseudo-element to accomplish our technique:

content Rather than create unnecessary mark-up to display our caption, we’ll use CSS generated content to add the caption.

As you can see from above, the mark-up is very simple and the use of the content property allows us to create some great behaviour without the bloat. All it’s doing here is getting the anchor’s title attribute value and appending the content:after the anchor.

Make it sit nice

Now that we have some simple mark-up and are now displaying our caption on hover/focus after the image, we’ll add some extra CSS to pretty up the caption and make it sit over the image, rather than beneath it.

We first do some simple styling to the containing list item. The only style required here is the relative position. Using a relative position allows us to absolutely-position elements inside the list item.

Adding some more styles to our :hover pseudo-class, we absolutely position the CSS-generated content and give it a height, background, line height (this is the same as the height, so we can vertically-centre the text).

We also do the same for the :focus pseudo-class so someone who can’t use a mouse still gets the full experience.

A sprinkle of CSS3

Of course, I couldn’t resist using some CSS3 goodness to make it that little bit nicer. At this point, we’re just using the principles of Progressive Enhancement where browsers that are CSS3-capable will have a slightly better experience. Our effect will still work on CSS2-capable browsers (such as Internet Explorer) even after we’ve spruced it up with CSS3.

On the anchor I’ve added the CSS3 box-shadow property to create a nice drop shadow effect when the image is hover/focused on. The outline is set to none so that the dotted outline won’t appear when it’s focused on.

Normally this would be frowned upon, but since we are adequately showing that the image has focus by showing the caption, outlining the image and applying the drop shadow, it’s still obvious that the element in question has focus.

Note: It should be said that the box-shadow property has officially been removed from the W3C CSS3 draft specification for further discussion, however browser vendors appear to have no plans of removing it any time soon, if ever.

Using the CSS3 rgba() property, we can make the background slightly opaque so that the image can be seen beneath our caption. Setting rgb before our rgba value ensures that browsers such as IE8 still show a background.

By adjusting the box model, the technique can further extend the caption by utilising box-sizing to our advantage, and so we can keep this technique as flexible as possible by making the overlay cover half the image and have the content run down the side.

With a few adjustments, it’s quite simple using this technique.

The box model—by default—adds padding and borders on top of the height that is set, and since we are setting our height to a 100%, this will essentially push out our overlay by a few pixels.

To change that behaviour, we utilise the CSS3 box-sizing property and set it to border-box. This allows us to set our percentage value and have any padding and borders calculated in conjunction with our height, so as not to push it out like it naturally does.

By default box-sizing is set to content-box. IE8 obviously doesn’t support this property, however IE’s box model naturally behaves like it was set to box-sizing: border-box and therefore doesn’t need any special treatment to work.

Mozilla and WebKit based browsers require their specific prefixes, whereas Opera supports it without any need for a prefix.

With a small addition to our original reverse class, adding right: 0, we can create some reusable CSS to reverse it either horizontally or vertically without affecting either of the anchors that have the .reverse class. Depending on the caption type— horizontal or vertical—the .reverse class will handle either situation correctly.

It wouldn’t be CSS if IE didn’t do something funky

Of course, IE8—ironically, the first IE browser to support the full CSS2.1 spec—has got an issue with generated content.

Upon initial testing, I thought IE8 didn’t actually support generated content as when I hovered over the image, nothing was showing up.

After some testing and using a text colour that contrasted with the image, I noticed that the background colour wasn’t showing up, but the text was.

So then, I thought at least it still works, just not with a background. Not content with that, I investigated further and discovered that the background colour was appearing behind the image. Don’t ask me how or why this is happening.

I came up with a solution that fixes this issue and allows the CSS-generated content and its background to appear over the image like it does in the other browsers.

Basically, we give the image a relative position and set the z-index to -1 to force it under the generated content.

We then have to reset the position back to static for the better browsers as position relative causes havoc with the caption overlay. I utilised the CSS3 not() pseudo-selector—which IE8 doesn’t support—and set the position back to its default behaviour of static.

Putting it all together

Let’s put it all together into a fully working version.

You can see a demonstration of the snazzy hover effects using various images sizes to show its flexibility.

Here’s the full markup required to create a single image with caption overlays. The demo page has more images on it, as well as demonstrating changing colours and shifting the overlaying caption into different positions as explained earlier in the article, just to show various potential tweaks and use cases.

Wrap up

We now have a simple technique that’s very capable using only CSS2.1. Of course, I also showed how to spruce it up with some additional—but not critical—CSS3 to make it a little nicer in more modern browsers.

We have good browser support; it works in all the latest release browsers.

And we made sure the technique was keyboard-accessible so that if you don’t or can’t use a mouse, the technique still works.

What do you think? Will you be using any of the techniques I’ve mentioned above? Why or why not? Share your thoughts and questions in the comments.

Related Content

About the Author

Ryan Seddon is front-end developer based in Melbourne, Australia. He loves to tinker with CSS, JavaScript and coming up with new techniques. You can find his discoveries and articles at his blog, The CSS Ninja. You can also connect with him through Twitter: @thecssninja.