Advanced hover states using CSS

Apr 1
 
Advanced hover states using CSS

The hover pseudo-element in CSS can be a powerful tool in a front-end developers arsenal, it’s not only for changing a links colour. In good browsers the hover element can be applied to almost anything but unfortunately ie6 & 7 only support the hover selector on the anchor tag, but of course that isn’t going to stop us accomplishing something cool. I’ll be looking at using the hover pseudo-element to add some clever functionality when a user hovers over an image.

In the above example we can see all the examples of the hovers using nothing but the hover pseudo-element on the surrounding anchor tag. This example uses a few gracefully degrading elements so if the browser doesn’t support the property it will still render fine and function as expected.

Cross browser support

This example has been tested in and works in the following browsers

  • IE6+
  • Firefox 1.0+
  • Opera 9.25+
  • Safari 3+
  • Chrome 1+

Roll overThe CSS Ninja

We’ll deconstruct the above example and see how it all comes together.

The xhtml

<a class="feature01" href="#">
	<span class="overlay01">
		<span class="caption01">Roll over</span>
	</span>
	<img src="location/to/image" alt="The CSS Ninja" width="200" height="206" />
</a>

The above code is pretty basic a simple anchor tag with a class the image that displays and the overlay and caption we want to show when the user hovers over the image.

The CSS

a.feature01
{
	display: block;
	border: 1px solid #dfd0cb;
	border-width: 0 1px 1px 0;
	margin: 20px 20px 1em 20px;
	float: left;
	position: relative;
}
a.feature01:hover { border-color: #000; }
 
	a.feature01:hover .overlay01
	{
		position: absolute;
		z-index: 3;
		width: 194px;
		height: 200px;
		border: 3px solid #fff;
	}
		a.feature01 .overlay01 .caption01
		{
			position: absolute;
			height: 30px;
			line-height: 30px;
			width: 100%;
			z-index: 3;
			text-indent: -9999em;
			color: #000;
			font-size: 11px;
			bottom: 0;
			overflow: hidden;
		}
		a.feature01:hover .caption01
		{
			text-indent: 10px;
			background: rgb(255,255,255);
			/* for browsers that know rgba */
			background: rgba(255, 255, 255, 0.75);
		}
		a.feature01 img { display: block; }

The break down

Now the CSS is a bit more involved but is relatively straight forward with a bit of explanation.

a.feature01
{
	display: block;
	border: 1px solid #dfd0cb;
	border-width: 0 1px 1px 0;
	margin: 20px 20px 1em 20px;
	float: left;
	position: relative;
}

The anchor tag is converted to a block level element and has its position set to relative so we can move around the span tags inside.

a.feature01:hover { border-color: #000; }

The border-color change applied to the hover pseudo-element is there so IE6 will actually activate the hover this is due to a weird bug in IE6 that will not activate internal items that are changed when hovered over, unless something is applied directly to the hover pseudo-element, in our case a border. This can also be fixed by using background-color: transparent which is the least destructive property if you don’t actually want to modify the anchor itself on hover.

a.feature01:hover .overlay01
{
	position: absolute;
	z-index: 3;
	width: 194px;
	height: 200px;
	border: 3px solid #fff;
}

The .overlay01 span is styled on hover as we only need it when the user hovers over the image. Its converted to a block level element, positioned absolutely and given a width and height of 6px less than the image width/height. This is because of the 3px border that sits over the top of the image. If you decrease or increase the border you will need to adjust the width/height accordingly.

a.feature01 .overlay01 .caption01
{
	position: absolute;
	height: 30px;
	line-height: 30px;
	width: 100%;
	z-index: 3;
	text-indent: -9999em;
	color: #000;
	font-size: 11px;
	bottom: 0;
	overflow: hidden;
}
 
a.feature01:hover .caption01
{
	text-indent: 10px;
	background: rgb(255,255,255);
	background: rgba(255, 255, 255, 0.75); /* for browsers that know rgba */
}

The .caption01 span is also position absolutely to the bottom of the anchor tag so the caption will display in a useful position when it’s hovered over. line-height is set to the same value as the height so the text will sit vertically centered. We also set a negative text-indent to hide the text when the hover is inactive; on hover we set the text-indent to a positive number and set the background-color twice using rgb and rgba. This will give it a nice transparent effect, and a solid rgb color for non-supporting browsers, gracefully degrading the transparency.

a.feature01 img { display: block; }

Finally the image is given a display block so we don’t get a gap between the anchor tag and image.

A little fun

So you may have noticed that the 3 middle images in the example above have an extra word appear when you hover. If you took a look at the example page html you may have noticed that the caption text is using the after psuedo-element along with the content property to dynamically add content through CSS. This is another gracefully degrading technique that will fall back to the generic text if it’s not supporting.

a.feature04 .overlay01 .caption01:after { content: ' more!'; }
 
 

Post filed under: css, xhtml.

Skip to comment form.

Comments

  1. Looks overcomplicated.

    You could just add a different background image to a:hover {} and do away with the rest of the markup (or use a sprite technique)

    Leo Horie, April 2nd, 2009
  2. Yes very true it can be done that way, but then you will be calling a separate image possibly having a slight delay of nothing showing when the user initially hovers.

    You would lose the flexibility of this technique by using images to create the hover overlay. What if you need to make the border thicker or even a different colour? You would need to re-cut the image(s). Using the way described in the article you only need to adjust a few properties in the CSS.

    The Css Ninja, April 3rd, 2009
  3. Fantastic — thank you! I’m using it on http://gallery.tryhandmade.com

    One question: instead of “overlay: hidden;” do you mean “overflow: hidden”?

    Thanks,
    Erika

    Erika Jurney, September 16th, 2009
  4. Thanks Erika. Yes that is supposed to be overflow: hidden good pick up, will fix that in the article now.

    The Css Ninja, September 16th, 2009
  5. hey can this be use in PHP as well?..i tried this but couldn’t make it.it works in chrome with a little more gap in between the image.and with firefox and ie it doest seems to work.it seems to be really cool.can you help me with this?.cant figure out the problem

    suraz, December 11th, 2009
  6. PHP is a serverside technology, this demo will work irrespective of what serverside language you are using. As long as you feed out the correct styles and markup it there shouldn’t be a probelm.

    Without seeing any markup or example page it’s hard to to tell what the issue is.

    The Css Ninja, December 13th, 2009
  7. I want to say a big THANK YOU! I was trying to implement a javascript version of this (using a jquery ‘tooltip’ type plugin), but it got unwieldy and too complicated with the scripts I had running on the page. The CSS version is a godsend, because I know it’ll just work! Thank you for sharing!

    Abbey, December 25th, 2009
  8. hi there, well i got the css code to work on FF,IE7 and 8 but not on IE6… even after adding the transparent background on the hovered element.
    any ideas?

    alex, December 28th, 2009
  9. I would go back and compare your html/css to my demo and see if anything has been missed.

    The Css Ninja, December 29th, 2009
  10. I had the same problem with transparency for IE, so I added this under the rgba:

    /* http://www.quirksmode.org/css/opacity.html */
    -ms-filter:”progid:DXImageTransform.Microsoft.Alpha(Opacity=80)”;
    filter: alpha(opacity=80);

    Abbey, December 29th, 2009
  11. thanks a lot…i used the code you gave and it worked beautifully.
    the only problem was that since we are not mentioning the image element – img directly, there was a border appearing around the image, the default color which appears after we use an image as a link.
    So after
    a.feature01:hover { border-color: #000; }
    i used an additional line:
    .feature01 img { border: none; }

    anish, January 5th, 2010
  12. Truly a css ninja, you be!

    I just used this wonderful rgba technique on my personal site, http://www.adamjohnsondesign.com/ in a rather alternative way.

    I switched the rgba transparency to be on the regular state and changed the alpha opacity to 0.0 on the :hover.

    One question though (something that I cannot figure out): I used a transparent PNG for IE7 and IE8 (due to their lack of support), and, in IE8, if you click on one of the images, then go *back* to the homepage without moving your cursor at all, some of the image is not covered by the transparency. What gives?

    Any suggestions?

    Wonderful technique. I commented out my hover_styles.css code pretty heavily; so, anyone looking for in line help should find that very easy to understand.

    Adam Johnson, February 4th, 2010
  13. More info about IE8 weirdness with repeating transparent PNG’s.

    It seems other people were having this issue as well. See http://stevelove.org/2009/07/10/png-background-repeat-bug-in-internet-explorer-7-and-8/

    The png set to repeat was 1x1px in size. The article above says to increase the size of the png. I did this (my divs were 200×200) and made a 10x10px png (found I had better results with images that could divide into 200 with a round numer). Now, the bug seems less apparent; however, still appears upon hitting refresh occasionally.

    Thoughts?

    Adam Johnson, February 4th, 2010
  14. @Adam – Looks great on your site. As for your issues with the transparent PNG I have got a solution that can bypass needing to use images to do the transparency. If you take a look at the revised version in IE6+ you’ll see that the caption overlay is now transparent, it uses the filter property along with Microsoft’s implementation of gradient.

    Basically it blends between the same colour, so there is no real gradient, and sets the transparency so you can see the image behind it.

    I will update the article when I have some time, so any questions just leave a comment and I’ll try to help out.

    The Css Ninja, February 5th, 2010
  15. Heck Yeah. That is pretty awesome. I will have to get that up and running on my site.

    Where do you find those crazy IE only css selectors? I am having trouble trying to find resources on them.

    Thanks for the help!

    Adam Johnson, February 5th, 2010
  16. Well I should mention that img { border: none; } should also be added to the stylesheet.
    And while we right click on the image why doesn’t the right click menu show the options such as view image, copy image etc.

    Ashish, February 10th, 2010
  17. @Ashish – img { border: none; } is already in the stylesheet. The right click issue is due to the absolute positioned span that sits over the image when hovered on, the context menu is in relation to the span and not the image.

    The Css Ninja, February 10th, 2010
  18. IF IE body class:

    I noticed here ( http://css-tricks.com/snippets/html/add-body-class-just-for-ie/ ) that they have a closing conditional statement for the IE (Although, I think they missed the “/”, right?). Thoughts on this? Is this extra since the body is already closed?

    Gotta love IE…

    Adam Johnson, February 25th, 2010
  19. Not sure what your trying to say there? I use that exact trick on the revised version I showed you earlier and I think it’s great.

    The Css Ninja, February 26th, 2010
  20. Ah, nix my last comment. I missed the ! on the css-tricks example. Although, is that even necessary? Seems like a regular old without any conditional statement would work (and does work) fine.

    Adam Johnson, February 26th, 2010
  21. The ! is needed so other browser just interpret the conditional comment as just a comment and ignore it.

    The Css Ninja, February 26th, 2010
  22. SWEET! :)
    USING THIS TECHNIQUE ON OUR CASINO SITE :)
    Tnx!!

    ZIGGY, April 16th, 2010
  23. hey sorry to sound like a dumass but im trying to tweak your code

    can an image appear instead of caption01 text on top of the color overlay

    how do i code that?

    thanks!

    cheeky, May 20th, 2010
  24. @Cheeky – You could apply a background image to the caption container or remove the caption all together and apply a background image to the overlay container on hover.

    The Css Ninja, July 5th, 2010
  25. Just found your site today and must say I’m really impressed with all the work you do. Just wanted to say a big THANK YOU!!!
    May the force be with you! or how do you ninja say that ;)

    gordon, July 26th, 2010
  26. Thanks heaps, I was having issues with my own solution with background flickering on IE7 of the overlay but this one worked perfectly for me in IE.

    Frank, August 4th, 2010
  27. Thanks for posting this! We are utilizing your code on our portfolio page. Works beautifully for what we intended!

    Michael Carwile, March 4th, 2011
  28. No problems with getting this to works, and changing a few things. however, I am trying include a span class with a description over the image by default . On hover I want to show a block with hover text, in addition to the default overlay. I cant seem to get any text to render over in image in the default state at all (unless I take away the text indent: -999, but then it does nothing on hover)

    Michael, April 21st, 2011
  29. @Michael

    You could have two spans in your description container that alternate the display of them based on the :hover pseudo-class.

     
        No hover
        Hover

    And then in the CSS just select the hover to show and the other span to hide when the anchor is hovered over.

    a:hover .caption01 span {
        display: none;
    }
    a:hover .caption01 .hover {
        display: block;
    }
    The Css Ninja, April 21st, 2011
  30. Hey that rocks,

    can be applied to any size image as a hover effect! much better than calling a secondary .png especially if the image is 800px wide on the page and you want a hover effect on that!

    Thanking you very muchly :-)

    plus you can echo any php you might have straight over the top woo hoo!

    jonnypixel, May 4th, 2011
  31. Thanks for this code! It’s a vast improvement to the image mouseover I would have gone with otherwise.

    Jessica, May 13th, 2011
  32. I spent three days racking my brains out over this issue and finally came upon your coding. I am not a programmer, but have become somewhat proficient due to lack of competent help. Your code was the answer and after some simplifications and modifications it worked absolutely great!!! You’re fantastic. Thanks for posting this helpful information.

    I have another question. I am trying to make an instruction string of text flash in red and yellow back and forth constantly with adjustable time intervals. I use a MAC and mostly firefox 4.X, but would want this to work in Safari, Explorer and any other major, noteworthy browsers. Would you happen to know the coding for that function? I can talk by phone too if you want, but I’ll check off your e-mail box for now. Thanks.

    Peter

    Peter, June 19th, 2011
  33. Never mind. I figured it out “The Flashing Text in Two Colors question.” But thanks anyway.

    Peter, June 19th, 2011
  34. I was looking for quite some time to find this solution, thank you very much for this tutorial!

    The ability to overlay and edit the content without ever having to open an image editor is fantastic.

    DoMo, October 8th, 2011
  35. Is it possible to use this technique on an imagemap so that there’s multiple captions? I don’t like the feel of using tooltips as the caption.

    If so, how? I’m pretty new at the whole CSS concept.

    Kristen, October 19th, 2011
  36. @Kristen

    Not really imagemaps are notoriously difficult to any sort of css styling to them.

    Ryan Seddon, October 23rd, 2011
  37. Really good tutorial. Thanks for share your knowledge.
    i used your css and it works perfect, but when i put
    it doesn´t work. Any advice about it.

    Thank you

    jaime, January 15th, 2012
  38. media=”handheld” it stops working, would you mind to recomend me something to repair this issue?

    thanks

    jaime, January 15th, 2012

Trackbacks

  1. [...] Advanced hover states using CSS | The CSS Ninja – All things CSS … [...]

    Advanced hover states using CSS | The CSS Ninja - All things CSS … | Best Web Gallery, April 2nd, 2009
  2. [...] Advanced hover states using CSS [...]

    網站製作學習誌 » [Web] 連結分享, April 8th, 2009

Leave a comment