Animate text over images on hover without JavaScript

A couple of months ago, I published a tutorial showing how to show text over images on hover without using JavaScript. When I presented to an HTML5 Meetup Group a couple of weeks ago, I took that idea and ran with it, adding some extra special animations, and I’ll show you how to do it too. Here’s what we’ll be creating:

There are three animations happening simultaneously when you move your mouse over each image:

  1. A zoom effect on the image itself, created by scaling the image up 140%
  2. The text and its transparent black background fading in
  3. The text dropping in from the top

You’re free to use all of the animations or to remove 1 or 2 of them – it all depends on how you’d like your final product to look. Let’s take a look at how to accomplish this.

1. HTML Markup

I’m going to put the images in a list, and then use the HTML5 figure and figcaption elements to hold the images and associated text:

2. CSS Styles

First up, we’ll modify the list style so that our images display side-by-side rather than in a list with bullets as they usually would. I’m going to use Eric Meyer’s reset, and then add these styles for the list of images:

We’re also setting a width and height for the list items, images, captions and the paragraphs inside the captions. We position the captions over the images, but set their opacity to 0 so that they’re not visible.

3. Show text on hover

Now let’s add a bit of CSS to show the text on hover:

This just changes the opacity of the figcaption to 1 when the list item is hovered. Now we can see the text. This will work just fine in most browsers, even if they don’t have support for the other CSS3 tricks we’ll be adding in the next few steps.

4. Zoom the images

Now it’s time to dig into adding the animations. Let’s tackle the image zoom effect first. I mentioned earlier that this is accomplished by scaling the images up 140%. Here’s how we’ll do that:

That first selector, for .photo-grid img was already in our CSS file. We’re just adding a CSS transition – along with the required browser prefixes. Then, we’ll add a :hover pseudoclass and add a CSS transform to perform the scaling, with browser prefixes.

5. Drop in the text

Next, let’s tackle that dropping-in effect on the text.

Just like with the image zoom, the .photo-grid figcaption p selector was already in our CSS. We’re just adding in the CSS transition. Then we add in a CSS transform to move the text 40px down.

6. Fade in the caption

Finally, let’s add the fading effect for the figcaption.

Here we’re adding two new CSS properties – a transition and a transition-delay. Because we’re zooming the image and dropping the text, we are going to wait a beat to start the fading effect so that the other animations aren’t lost in the shuffle.

And that’s it. Once again, our example is progressively enhanced. For those people who visit our page using browsers that don’t support CSS transitions or transforms yet, they’ll just see the figcaption and text appear when they hover their mouse over each image. But those who do have capable browsers get a little extra treat. And these are just the tip of the iceberg. Use your creativity to invent new animation combinations. Then share your links here so we can learn from each other!

Image credit: Moyan Brenn

80 thoughts on “Animate text over images on hover without JavaScript

  1. This was such a lifesaver! The explanations were understandable and it’s a well-constructed tutorial.

    Thank you so much! You’re great. 🙂

  2. For some strange reason, I’m having a hard time with the text becoming slightly transparent. Any suggestions?

  3. Is it possibly to use this with a auto height rather than a fixed height? Dealing with responsive images I would like to to stay the same size as the image.

    Is this possible?

    1. Let’s try that again haha…

      Is it possibly to use this with a auto height rather than a fixed height? Dealing with responsive images I would like the container to stay the same size as the image.

      Is this possible?

  4. Thanks Natalie for such an awesome tutorial! One quick question, could this be made to work with two different links in the image? Or is this only possible using javascript?


  5. I noticed that on mobile, when I click on the image, it shows the hidden info briefly and goes on to the Flickr link automatically. Is there a way to let the user choose whether or not he wants to click through to the link? If the title is long, I want the user to be able to read the entire title before deciding whether or not he’d like to move on.

  6. This is a great tutorial.

    I have an Image Map: with 100 “areas”

    Would like to leverage what you have here, to display a single, fixed display anywhere on the page.

    When the User “hover/ mouseover” the Imagemap “areas”, the ‘title’ attribute or “id (text)” is displayed in the fixed display.

    Any references / pointers would be greatly appreciated. DZ

  7. Great tutorial thanks! Just wondering if this can be used to hover over an image to ‘call up’ another mapped image? Cheers in advance

  8. What if you want this to work with circular images? I adjusted some elements so that the hover shaded area is a circle, and I have tried to add circle style elements to other sections, but the zoom in does not border on the circle. it zooms in as a square, and then corrects itself to be a circle after all the transitions/zooms

      1. Hi.
        Thanks for this example, it’s exactly what I’m after – however I can’t seem to get it to work with my current code… I need to add it to:

        Fade-in Hover Text



        How do I add this to my CSS to get it to work, please?

  9. I’ve to apply it on my website that is built by foundation framework. But the width of these grids are not setting up with the default width of foundation 5. Is there any solution?

  10. Loving your work nataliemac! If i need the text in from the start can it be separated from the transparent black background? Any pointer in the right direction would be much appreciated…

  11. Hi Natalie, thanks for posting and sharing this with us. However….none of your code on the article is showing up for me. It’s showing up when I inspect the element of the page, so I know it exists, but it doesn’t show through on the actual site. Any chance of fixing this?

  12. I’m very new to HTML and trying to edit the script to have a zoom/text of the countries i’ve visited.

    My other images are set at W:461 H:333.
    However when I try to amend the html for the effect the size becomes much smaller and the text effect is on the left.

    Any idea’s?

  13. This has been wonderfully helpful. I was trying to get a simple text-over effect without resorting to bloody jquery or scripts. Thank you.

  14. Thanks a ton! It really transformed a page from text-based links to wonderful animated ones. I use google-sites, and had to do a lot of tinkering to get the transform to work properly. The other annoyance, not sure if it is Google Sites, is that each of the link opens in its new window… not sure how to force it to open in the same. If you know, please shoot a reply, else, I will keep tinkering.

  15. Hello i tried to implement this and it worked beautifully.
    Yet i have one question how to align images horizontally i.e in a one line? One after other and so on.

  16. Hello,

    thaks a lot for the code!!

    I’m trying to make the images a little bit bigger. But somwhow it’s not working. Can you please explain me what values I habe to change?

    Thanks and regards


  17. Thank you so MUCH for your solution, YOU ARE A GODSEND! I’ve been learning how to code on my own, but the biggest trouble I have run into while entering this realm is being able to proper solutions to my problems since everyone has a different solution and a different design they want to accomplish.

  18. Excellent work Natalie MacLees thanks,
    but its working fine in big screens but not working as expected in mobile phones can you please tell me the way i can solve the issue.

  19. Thanks for sharing this splendid image caption technique! Worked like a charm for me, including responsiveness on smaller screens. You’re awesome. 🙂

  20. Small world Natalie! Tutored with your class a few weeks back in LA. Great content – thank you for the great description!

Leave a Reply