Slide In Image Captions

Published by Chris Coyier

Reader Jason Lucchesi send me in a neat demo of image captions sliding in overtop an image on rollover. The effect used a bunch of nested divs to get it done, so I thought I'd do my own version of it using the standard HTML5 structure for an image with a caption, and CSS3 it up.

View Demo   Download Files

Why do something like this at all? Perhaps saving space in a layout. Perhaps the captions themselves are a distraction in a specific design and it's cleaner to only reveal them conditionally. I dunno, it's just a demo. If you don't like it, don't use it.

HTML5 Structure

Nothing here other than pure and semantic markup of an image with caption.

<figure>
	<img src="yay.jpg" alt="">
	<figcaption>
		yay!!!
	</figcaption>
</figure>

CSS Structure

The figure element wraps everything and is our basic building block. The empowering concepts start here. The figure will need to have position: relative; so we can absolutely position the caption exactly where we want it and not have it take up any additional space. We also need overflow: hidden; so as we do our sliding, the caption disappears outside the boundary of the figure.

figure { 
  display: block; 
  position: relative; 
  overflow: hidden; 
}

figcaption { 
  position: absolute; 
  background: rgba(0,0,0,0.75); 
  color: white; 
  padding: 10px 20px; 
}

Hot Sliding Action

We need to hide the captions so that we can reveal them with hot sliding action when the image is rolled over. Let's position the caption slightly beyond the lower left and hide it entirely with opacity. Then when the figure is hovered, we'll slide it into place and adjust the opacity back up. To get it to actually slide, we'll use transition.

figcaption { 
  position: absolute; 
  background: rgba(0,0,0,0.75); 
  color: white; 
  padding: 10px 20px; 

  opacity: 0;
  bottom: 0; 
  left: -30%;
  -webkit-transition: all 0.6s ease;
  -moz-transition:    all 0.6s ease;
  -o-transition:      all 0.6s ease;
}

figure:hover figcaption {
  opacity: 1;
  left: 0;
}

Options, options

In the demo, the position and slide in direction is different on each of the images. We do that just by adding class names to the figures and positioning things different according to the classes.

<figure class="cap-top">
.cap-left figcaption { bottom: 0; left: -30%; }
.cap-left:hover figcaption { left: 0; }

.cap-right figcaption { bottom: 0; right: -30%; }
.cap-right:hover figcaption { right: 0; }

.cap-top figcaption { left: 0; top: -30%; }
.cap-top:hover figcaption { top: 0; }

.cap-bot figcaption { left: 0; bottom: -30%;}
.cap-bot:hover figcaption { bottom: 0; }

So, how do people know there is a caption at all?

If you are going to go through the trouble of having fancy captions, it would be a shame (read: UX FAIL) if there was no indication they were even there. Let's indicate the presence of a caption with a subtle question mark indicator. Rather than using non-semantic extra markup to do this, we'll use generated content in the form of a pseudo element on the figure.

figure:before { 
  content: "?"; 
  position: absolute; 
  background: rgba(255,255,255,0.75); 
  color: black;
  width: 24px;
  height: 24px;
  -webkit-border-radius: 12px;
  -moz-border-radius:    12px;
  border-radius:         12px;
  text-align: center;
  font-size: 14px;
  line-height: 24px;
  /* Only Fx 4 supporting transitions on psuedo elements so far... */
  -webkit-transition: all 0.6s ease;
  -moz-transition: all 0.6s ease;
  -o-transition: all 0.6s ease;
  opacity: 0.75;	
}
figure:hover:before {
  opacity: 0;
}

Note there is no positioning values on the CSS above, despite the position: absolute;. The position will depend on the option classes we set up. You'll probably want the question mark placed in the corner the caption slides into. So like:

.cap-left:before {  bottom: 10px; left: 10px; }

Usage

As with anything you find on this site. Please use this on whatever you dang well please. Preferably big fancy corporate projects where you tell your boss this was all your idea and you get a big raise.