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 1×1px in size. The article above says to increase the size of the png. I did this (my divs were 200×200) and made a 10×10px 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

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