Content Overlay with CSS

Here's the problem: you have a container with some content in it like an image along with some initial descriptive text. Then, when users hover their mouse over the container, a hidden container is revealed to present additional information over top of the current information but in a way that retains content from the original container.

This was essentially the problem presented to me by Anton Peck. He had originally asked for a way to do this with JavaScript. To which I provided the following solution that didn't need to use JavaScript at all.

Check out the quick demo.

When you hover over the container, a new container is displayed over the existing content. The trick here is the use of position:relative to allow the static content to appear over absolutely positioned content.

This is the HTML structure that was used:

<div class="infobox">
   <img src="http://example.com/path_to_image.jpg">
   <div>Here's what you have.</div>
 
   <div class="more">Here's more of a description of what we have going on here.</div>
</div> 

And this is the CSS I used to pull off the effect:

.infobox {
	position:relative;
    border:1px solid #000; 
    background-color:#CCC;
    width:73px;
    padding:5px;
    }
.infobox img {
	position:relative;
	z-index:2;
    }
.infobox .more {
	display:none;
    }
.infobox:hover .more {
	display:block;
    position:absolute;
    z-index:1;
    left:-1px;
    top:-1px;
    width:73px;
    padding:78px 5px 5px;
    border:1px solid #900;
    background-color:#FFEFEF;
    }

The infobox is positioned relatively to allow me to position the more container in relation to the infobox. The image is positioned relatively to be able to apply a z-index to it (a number greater than the more container).

I did a quick test in Firefox and Internet Explorer 7 and 8 and this worked without issue. In IE6, this won't work because of the lack of hover support on anything but links. At which point, some JavaScript would need to step in to replicate this solution (maybe through the use of Dean Edwards' IE7 Scripts).

Update: Here's another example to help demonstrate the idea using a different layout for the additional content. This example would be harder to pull off with just show/hide or any other technique described in the comments so far.

Published March 26, 2008
Categorized as HTML and CSS
Short URL: http://snook.ca/s/883

Conversation

28 Comments · RSS feed
Adriaan Nel said on March 26, 2008

Hi Jonathan, the idea is rather nice, but how about making it a bit more eye friendly - IE: use a transparent overlay on the image and position the text within this overlay, over the image when hovering. I've seen what I speak of on some sites (just can't seem to remember exactly where right now) and it's quite nice, but as a basic effect this also works...

Another problem might be the display:none property of the .more div, google might think you are stuffing keywords in there...not that it should bother you, I just thought it should be mentioned.

Jeena Paradies said on March 26, 2008

I don't get it, why don't you just use:

.infobox .more, .infobox:hover div { display: none; }
.infobox:hover .more { display: block; }

Aditya Mukherjee said on March 27, 2008

@Jeena: Because your first and second declarations clash. You are trying to hide '.infobox > div' on hover, and showing '.infobox > .more' on hover ... which both point to the same thing. It could work, but might behave erratically on different browsers.

@Jonathan: It will be better not to use the 'position' attribute, but rather put the existing content in a DIV and hide it, while showing the '.more' content - something like what Jeena initially suggests.

Also, this is not so much of an overlay, as it is extending. Overlay would be to show something on top of an existing info (with transparencies) to give a sense of layers.

Ludwig said on March 27, 2008

Jeena: That wouldn't replace the old text with the new.

Aron said on March 27, 2008

Adriaan; Instead of using display: none; you could just set a large negative value on a left value:


.infobox .more {position:absolute; left: -900em; }
.infobox:hover .more {display: block; left: -1px; ...}

Just a thought.

Fouad Masoud said on March 27, 2008

check this out.
http://www.some1ne.com/d/slideImage/slideImage.htm

snook for IE6 you can simple use the csshover.htc
view-source:http://www.xs4all.nl/~peterned/htc/csshover.htc

Abhimanyu said on March 27, 2008

Nice, but for some reason it doesnt work in IE.

Ed Eliot said on March 27, 2008

One problem this approach seems to have is with keyboard focus. There is no way to expose the content without a mouse.

My feeling is that this functionality might best be implemented with JS. With JS disabled the additional content would be default displayed. With JS enabled it would be hidden (preferably off screen rather than with display: none so it's still accessible to screen readers) and displayed on rollover.

Jonathan Snook said on March 27, 2008

@Jeena: I had a feeling somebody would mention that. I had even written a paragraph but deleted it. Guess I should've kept it in. :) What I would have said was, "This example isn't the best because it could be done by simply hiding the current text while showing the new text. It's the principle that I'm trying to demonstrate, not the example I'm trying to solve."

@Ed Eliot: the accessibility issue here could be partially resolved by setting a tabindex on the div and setting up a :focus event (I believe that would work). But a nice javascript fade-in would be nice, too. :) but the CSS could still remain the same (which is really the point of this post).

Neal G said on March 27, 2008

You gotta love it when you can solve a problem with CSS that would require some convoluted javascript to create it otherwise, although that makes you wonder if behavior should be part of CSS rather than only javascript.

keif said on March 27, 2008

instead of doing two divs, what about extending the height? i.e. height of 150px with overflow:hidden, and on hover it we have it extended to a height of 200px (or 300, or whatever). (Ignoring the IE implications, at least)

Just a curious thought...

Jeena Paradies said on March 27, 2008

@Aditya: No you are wrong, if works because of the specificity. (See the great CSS Specificity Wars)

@Ludwig: Yes it would, try it yourselve.

@Jonathan: Ok I didn't get that, thanks for clearing things up.

Jonathan Snook said on March 27, 2008

@keif: the problem is displaying an overlay while retaining content from the original container. The look and feel of the overlay in this case could be completely different. Here's another example to help demonstrate the idea (and would be harder to replicate with any other idea presented here so far).

Aditya Mukherjee said on March 27, 2008

@Jeena: I missed the first <div> that holds the un-extended content. My comment was a royal waste :P

david said on March 28, 2008

very cool... it's got me thinking where it could be used.

andrej said on March 29, 2008

Great tip. Is there any restriction which html-elements you can apply the :hover attribute(?) to? Does work for lists, etc.?

Jonathan Snook said on March 29, 2008

@andrej: technically, the :hover selector works on any element. As mentioned before, IE6 is the lone exception which doesn't support it on any element BUT the <A> element.

Andrew Kumar said on March 30, 2008

no hover state in iPhone or wii

George said on March 30, 2008

How about... Change the parent DIV to an A, change the child DIVs to SPANs. Then add the following to .infobox:

display:block;
text-decoration:none; //remove link underline
color:#000; //reset to the correct text color

Then add:

.infobox span {
	display:block;
}
.infobox:hover {
	zoom:100%; //force IE6 to redraw upon hover correctly
}

You'd have to add an href attribute to the A element for this to work, though. Just make it href="#" or href="javascript:return false", or maybe you'd actually like it to link somewhere!

Anyways, this works (I tested it in IE6 & FF2; don't see any reason it won't work in IE7, Safari 3.1 and Opera) and thus you can run a fully IE6-compatible CSS-only solution to this problem.

With IE6 still reigning supreme globally at around 40% of market share, we still have to focus on solutions that work efficiently for this abortion of a browser.

Mr.Blue said on March 31, 2008

Hi Snook, I have been using these kinds of concept to apply on the new lay-out of 9tutorials.com. Actually, I use jQuery to play around with CSS, then it could prevent the cross browser problem.

Using CSS is a great idea, but it is in short of some visual effect, which we can implement from some popular Javascript framework

Bjarni said on April 01, 2008

Interesting, I like the idea behind it.

Jermayn said on April 01, 2008

I love it!!
I like seeing examples were css can be used instead of JavaScript all the time.

btw the first example is much nicer than the second example.

RubyShooZ said on April 06, 2008

Unless I missed it - this does work in IE7.

Peace, love and understanding to all.

Google said on October 28, 2008

Google
<img src="http://google.com/google.jpg" onClick="alert('Google');">

justin brock said on January 16, 2009

I get error pages when I click the links your examples. Have they moved?

Vi said on March 24, 2011

hi im using joomla/virtuamart, i've used this approach to our products, but i need a little help here. how can I have two overlay? options are right or left depends on the position of the product so it would look good with the site. tnx! hope to hear from you soon :)

Anita said on March 27, 2011

Tx for your informative blog. Not finding what I want, I would have to settle for the next best thing.

I am looking for position the text within the image, when hovering. like Adriaan Nel, I've seen on a site and searching for days to find similar. Ideally, image is still shown but maybe with some opacity but the white text is over the image. Thus info on image is shown within that image real estate and not to intrude on other image.

I am not strong on front end design and kicking myself for not saving that site. Save the directory site and did not realized the article was in a blog that changes. One month later when I needed the information could not recall the blog for that directory is over 400 links on web development. tx

I have look thru jslib and various site. Would take a shot with what I gather and hope to do. tx

Anita said on March 28, 2011

Found it and disappointed when tested on IE, did not want the degraded method for ie even thou it shows the description. Will look at this blog method since it can handle large description.

LO, the second best thing becomes the first. Would be nice if the java script is provided as a learning material even thou the author is for non-java script css. It is made clear he favors non-javascript design but it needs java for ie6. Tx for mentioning Dean Edwards.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.