Grow your CSS skills. Land your dream job.

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.

	<img src="yay.jpg" alt="">

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; }


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.


  1. Jonny007-MKD
    Permalink to comment#

    I really like this! Great work!
    It would be also nice to add a border-radius to the inner corner :)


  2. Ben Rowe
    Permalink to comment#

    Your site’s style is broken in chrome 11

  3. awesome, i will try it on my blog. hehe

  4. Keith
    Permalink to comment#

    Very cool. I expected some use of javascript would be needed for this. Thanks for sharing.

  5. Jon
    Permalink to comment#

    Looks good, though would be nice list list what browsers it does and doesn’t work in.

    • :before – all except < IE7
      figure, figcaption – HTML5 browsers.
      transition, border-radius, rgba, opacity will have an acceptable drawbacks.

  6. How do you incorporate this little trick in WordPress? I use the HTML5 version of TwentyTen for the theme in question.

  7. Neat. Very Neat.

    Quick suggestion, what if we replace “?” with “i”?

    • Permalink to comment#

      I have not really learnt much of html5 and only the main parts of css3.
      So what would happen?
      haha i really should spend some time learning it.

    • That will work just fine.
      The content property can hold pretty much anything really.

  8. Rob
    Permalink to comment#

    Armageddon Peter. Armageddon.

  9. Permalink to comment#

    Thanks … Great tip. Chris.!

  10. Bit unrelated here Chris but do you ever drink in the Prancing Pony?

  11. Permalink to comment#

    few days ago i was loking for such thing.

  12. Bunnyslippers
    Permalink to comment#

    Works in my version of Chrome, Ben.

  13. You forgot to mention an important style definition:
    img {display: block;}
    Without that, the figcaption does not align accurately to the bottom and right margin of the image.

  14. Sagar Ranpise
    Permalink to comment#

    This is great tutorial and this has both HTML5 and CSS3! Also, the new look of the site looks really good with CSS3 and HTML5…

  15. Permalink to comment#

    Very nice demo : )

    It would be nice of you also minimize the CSS code as you did with the HTML5 markup, for example:

    you don’t need vendor specific prefix for the border-radius, only border-radius: 12px; will work in both Firefox and Chrome without the need of adding -moz- and -webkit-

    I think this will work on IE9 as well (didn’t test it) but probably you’ll have to declare all corners border-radius: 12px 12px 12px 12px; for it to work on IE9.

    • Permalink to comment#

      IDK how to edit my previous comment, but I wanted to point out that I was talking about current browsers versions (Chrome10, Firefox4, & IE9)

  16. Gavin
    Permalink to comment#

    I am noticing a change in your tone Chris. Maybe its just me
    A great demo of using the new HTML5 tags.

    I’ll try and implement it in a sidebar, often a place where space is tight.

    Thanks again.

  17. Permalink to comment#

    First there was “PFF! Fuck flash”.
    The Time has come “PFF! Fuck JavaScript.” :)

    • Please star offensive or obscene words next time. You know, kids/young adolescents also view this website.

      Thanks =)

  18. Really Great work .. i like this .

  19. Doesn’t work in IE8 and below, but still a very cool experiment!

  20. Awesome, got to try this at once.. thanks for sharing. Downloading now.

  21. Nice one Chris :) I have done something similar some months back –

  22. I think we’ll be seeing plenty of this in the near future. Seems like a fantastic alternative to the joys (or not so) of Jquery and Flash to do similar tasks – nowhere near as long winded as well! Personally I’ve not took the plunge into the depths of HTML5 (purely due to the BETA feel of some aspects) as of yet, but in my next site I’m going to have a play around with some tricks such as this so thank you for getting me excited! I can see some really nice designs coming from HTML5 tutorials such as this one in the future!

  23. snilloR
    Permalink to comment#

    Nice. Clean and effective, and clearly explained/demonstrated. This is something I’ll use.

    (BTW, I really like having the CSS and markup shown separately at the right in the demo.)


  24. Helge
    Permalink to comment#

    Very nice, Chris, love your work!

    The bit about Usage really made me smile..

  25. Joshua Parker Toulson
    Permalink to comment#

    Cool, although we now this won’t work in IE, and every client I have – everything must always work in IE 6 and up. Man I hate IE. Pick your version.

  26. Integrating this with the Anything-Slider (optionally of course) seems like a good idea.

    Everyone, especially Chris, what do you think?

  27. Permalink to comment#

    That’s freakin’ awesome! Thanks! Time to change my code and use this one instead… LOL

  28. ozira
    Permalink to comment#

    I like it !
    Thanks for sharing Chris

  29. Permalink to comment#

    This actually degrades pretty nicely in IE7/8. The captions sort of peek out giving the indication that they exist at all. They don’t smoothly transition, but they do come out.

    With IE6, you’d just make remove the hidden state and this would be perfect. Pretty cool technique.

  30. Thanks so much man this is great!

  31. Chris im having some trouble with getting the captions to work on firefox and not entirely sure why?

    Here is the website mock up it works perfectly fine on chrome but firefox just fades out the ? box ne ideas?

  32. Hey, wonderful! I don’t know if I’ll be using it in the future or not but I sure am looking forward to learning HTML5 & css3 and here’s another one to learn !!

    Thanks, it’s wonderful because its short and its really easy!!

  33. Permalink to comment#

    i think this can be done with jQuery Cycle with “shuffle” effect

  34. Thank you for your idea. I will test it on my own website, because i like it.

  35. arif
    Permalink to comment#

    i think this can be done with jQuery Cycle with “shuffle” effect

  36. this feature is avilable in “Autofocus” theme in WordPress repository
    love css-tricks want to be able to do it all, would be learning slowing a post a day

  37. Thanks so much! i like it

  38. It’s nice trick to use question mark, to let people know there is caption, obviously people would hover that little question mark out of curiousity, and that would reveal the caption.

    Nicely formatted code. And yet I got to learn some HTML5 tricks.

    Keep up with the good work.

  39. Hey Chris,

    I think i’ve stumbled across a workaround for the captions in ie….

    was trying to make a workaround for ie, as it constantly displayed the caption on top…and worked well in other browsers..

    so i added the following modifications to your code:

    visibility: hidden; to the figcaption in css
    and added
    visibility:visible; to the ‘figure: hover figcaption’ in css

    and it works in ie…not the same effect, but still works
    just tested in ie 8, 9, safari, firefox and chrome and it works fine….
    the downside is that you will lose the “?” on the image

  40. Very nice script, I will try to implement it and see how it works. Love html5!

  41. Hi everyone i found the solution !! It’s working on IE8 !

  42. I am amazed about that effect; first time I saw this effect on phone arena, where each phone showed it’s short description.

  43. Permalink to comment#

    it looks nice, and functions very well… but im still partial to HTML4 :)

  44. Wow – I’m impressed. Very nice! BTW maybe my Drag and drop will impress you ;)


  45. Permalink to comment#

    Such a nice effect!!

  46. Nice! I use it on my blog and i LOVE it!

    But I want to ask something. Why the caption is on the outside of the image when I make the image smaller? Is there any way that the caption can adjust by itself when I change the dimension of the image?


  47. vikash bharti

    very nice

  48. Joshua
    Permalink to comment#

    This code works great but how do you center the image?

  49. Sudhanshu Pandey
    Permalink to comment#
  50. For some styling i removed the “?” with the “⇪” and but in in a box instead a circle, looks really nice!

  51. Charlie

    Demo is no longer working in Firefox 29.0.1. Looks okay in MAC Chrome and Safari.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".