Create an Image Hover Effect with Text in WordPress

Create your own image hover effect

Hi Ashley –

I want to create a page for specific books, but I want as little text as possible on the page. Instead, I would like to make it so that the book synopsis pops up when you hover over the image (instead of having something like a gallery where you need to click to engage the info). Is there a plugin you recommend for this?



Hi Jennifer!

If you’re looking for a plugin in the repository, then sadly, I’m not the girl to ask.

I’m the girl who codes it from scratch! Yeehaw!

If you’re a lean, mean, coding machine, then buckle up and I’ll help you code this 100% yourself. Or if you just want the ready-made plugin you can get that at the end.

Let’s talk about our future epic plugin.

  • We’ll be creating a new shortcode that looks like this: [hover-effect image="image URL here" alt="alt text for the image"]Text you want to appear on hover here.[/hover-effect]
  • When you load the page, you’ll just see the image(s).
  • When you hover over the image, the text will appear next to it.

Are you ready, boots??

Create that plugin file, girl!

If this isn’t your first rodeo, you know what this part is all about. Create the plugin folder and file.

  1. Create a new folder on your desktop for the plugin. No spaces in the folder name, please! All lowercase with hyphens ( – ) is best. I’m going to go with ng-image-hover.
  2. Open up your text editor of choice. I use Phpstorm because it’s bomb for coding. Other free alternatives are: Notepad++ (Windows) and TextWrangler (Mac).
  3. Create a new file in that folder you just created. Give it the same name as the folder but with .php on the end. I’m going with ng-image-hover.php

Once you’ve got your file created, you need to add the plugin comment block to the top. This bit of code is a comment that tells WordPress, “Hey girlfriend! I’m a plugin! Make sure you recognize me in the plugins menu.”

Here’s what it looks like:

 * Plugin Name: NG Image Hover Effect
 * Plugin URI:
 * Description: Simple shortcode that shows hidden text when you hover over an image.
 * Version: 1.0
 * Author: Nose Graze
 * Author URI:
 * License: GPL2
 * @package ng-image-hover
 * @copyright Copyright (c) 2015, Nose Graze Ltd.
 * @license GPL2+

Of course you can change the Plugin Name, Description, etc. to whatever you want.

Next, let’s create a new shortcode and make it do stuff.

Here’s the skeleton of the piece of code for making a shortcode:

 * Shortcode
 * Creates our shortcode for the image hover effect.
 * @param array  $atts    Attributes for this shortcode.
 * @param string $content Content in between the shortcode tags.
 * @return string
function ng_image_hover_shortcode( $atts, $content = '' ) {
	$atts = shortcode_atts( array(
		'image' => '',
		'alt'   => ''
	), $atts, 'hover-effect' );

	// Stuff to go here!


add_shortcode( 'hover-effect', 'ng_image_hover_shortcode' );

You’ll want to put this directly below the comment block we created before.

Let me break it down for you.

  1. That bit at the top surrounded by /** */ is a comment. It’s basically a description of what we’re doing. This is just to help you remember what’s going on in your code.
  2. Then we create a new function. I called mine ng_image_hover_shortcode. The name isn’t important, but it must be unique. Two functions can’t have the same name (even if they’re in different plugins/themes!). That’s why it’s good to always prefix yours with something unique (like I prefixed mine with ng_image_hover_ which is the name of my plugin.
  3. The function takes two arguments: the attributes and the content. Here’s an example of an attribute: [hover-effect image="image URL here"]Text you want to appear on hover here.[/hover-effect]. See the bit I highlighted? The image="blah blah"? That’s the attribute. The content, on the other hand, is what appears in between each set of brackets. In the above example, it’s the words Text you want to appear on hover here..
  4. Then in the shortcode function, I left another comment showing you where we’re going to be working later ( // Stuff to go here! ). That bit comes next.
  5. Finally, after the function, I actually register the shortcode with WordPress. I tell it the shortcode exists. That’s this line:
    add_shortcode( 'hover-effect', 'ng_image_hover_shortcode' );

    The first item in the parenthesis ('hover-effect') is what you want the shortcode to be. You can change this to whatever you want. The second item ('ng_image_hover_shortcode') is the name of your function from before. This must match your function name!

Are your eyes starting to bleed from all this code?

I feel you, I feel you. This coding stuff can be tricky. If you just want to download the plugin and call it a day, you can totally do that at the end.

Take me to the plugin!

Let’s set up the HTML of our hover effect.

Before we can make the shortcode actually do anything (right now it does nothing) let’s figure out how we want our hover effect to look in HTML. Here’s what I’m thinking:

<div class="ng-image-hover">
	<img src="image url here" alt="alt text">
	<div class="ng-image-hover-text">
		Text that should appear on hover in here.

So with that in mind, we can now put that into our shortcode. (Note: Don’t actually paste the above code into your plugin yet. That comes next!)

Add the HTML into the shortcode.

Back to the shortcode code!

So find this comment in your shortcode function:

// Stuff to go here!

You can remove that, but that’s where we’re going next, okay? Right in there, add this:

<!-- Your HTML will go here in a minute -->
return ob_get_clean();

This bit of code lets us add some HTML to our function. Then, at the end (return ob_get_clean();) we send that HTML back to WordPress.

So now all we have to do is paste our HTML where I left the comment for it and start replacing our “placeholders”. So here’s how the whole function will look with just the HTML added in:

function ng_image_hover_shortcode( $atts, $content = '' ) {
	$atts = shortcode_atts( array(
		'image' => '',
		'alt'   => ''
	), $atts, 'hover-effect' );

	<div class="ng-image-hover">
		<img src="image url here" alt="alt text">

		<div class="ng-image-hover-text">
			Text that should appear on hover in here.
	return ob_get_clean();


But right now that HTML just has placeholders. Like “image url here” isn’t a real image—duh. So what we have to do is replace those with the data from the shortcode. It’s also important to make sure the values are safely put in our HTML.

Replace the ‘placeholders’ with real values.

For the image URL, that means code like this:

<img src="<?php echo esc_url( $atts['image'] ); ?>" alt="<?php echo esc_attr( $atts['alt'] ); ?>">

See how those values correspond to the pieces above? If you remember, the top of our function has this:

'image' => '',
'alt'   => ''

So now we use those same names to actually get them to display. $atts['image'] and $atts['alt']. This is an array, for you more advanced folks.

So we’ve taken care of the image, now let’s do the text. The text works slightly differently because we want to use the $content argument from the function. Like this:

<?php echo do_shortcode( $content ); ?>

We wrap it in do_shortcode() to allow you to use other shortcodes inside of this one.

So what happens if we use the shortcode right now?

If I were to activate the plugin and add my very first shortcode like this:

[hover-effect image="http://localhost/wp/wp-content/uploads/2015/10/the-collector-victoria-scott.jpg" alt="The Collector by Victoria Scott"]He makes good girls...bad. 

Dante Walker is flippin’ awesome, and he knows it. His good looks, killer charm, and stellar confidence have made him one of hell’s best—a soul collector. His job is simple: weed through humanity and label those round rears with a big red good or bad stamp. Old Saint Nick gets the good guys, and he gets the fun ones. Bag-and-tag.

Sealing souls is nothing personal. Dante’s an equal-opportunity collector and doesn't want it any other way. But he’ll have to adjust, because Boss Man has given him a new assignment:

Collect Charlie Cooper’s soul within ten days.

Dante doesn't know why Boss Man wants Charlie, nor does he care. This assignment means only one thing to him, and that’s a permanent ticket out of hell. But after Dante meets the quirky Nerd Alert chick he’s come to collect, he realizes this assignment will test his abilities as a collector…and uncover emotions deeply buried.[/hover-effect]

How would it look??

A bit like this:

Incomplete image hover effect

Before you get all like, “Girl, that’s not what I wanted!”—I know, I know. We’re not done yet! Take a breather.

But hey, right now we have a shortcode that’s actually working and doing something. If you do a little Inspect Element on that, you’ll see it’s using the HTML we told it to!

HTML in the image hover effect shortcode

Using CSS to pull the whole thing together.

What we need to actually make this work is a little CSS.

First, we need to tell our plugin to add a new CSS file to our site. To do that, add this code at the bottom of your file:

 * Add CSS
 * Includes our stylesheet on the front-end of the site.
 * @return void
function ng_image_hover_css() {
	wp_enqueue_style( 'ng-image-hover', plugins_url( 'ng-image-hover.css', __FILE__ ), array(), '1.0.0' );

add_action( 'wp_enqueue_scripts', 'ng_image_hover_css' );

This tells WordPress to add a new stylesheet that’s inside our plugin and is called ng-image-hover.css. So that means we need to create a new file inside our plugin folder with that exact name.

Here’s the CSS that I’m using:

.ng-image-hover {
    display: inline-block;
    position: relative;

.ng-image-hover img {
    cursor: pointer;

.ng-image-hover:hover .ng-image-hover-text {
    display: block;

.ng-image-hover-text {
    background: white;
    border: 1px solid #d2d2d2;
    -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
    -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
    display: none;
    width: 400px;
    max-height: 100%;
    overflow-y: scroll;
    padding: 1em;
    position: absolute;
    top: 0;
    left: 100%;

You can change this to suit your needs, but the main things you need are:

  1. Hide the .ng-image-hover-text class.
  2. Display the .ng-image-hover-text div when you hover over .ng-image-hover

The rest is up to you!

The final result! *drumroll*

Here’s how it looks when we first render the page:

Image when we first load the page

And if we hover over the image:

Text that appears on hover next to the image

Like a boss!!

Download the finished plugin!

I promised at the beginning that you could download the complete plugin if all this code makes your eyes bleed. I get it.

So here it is! Just pop in your email and the complete, ready-to-install plugin is all yours.

Photo of Ashley
I'm a 30-something California girl living in England (I fell in love with a Brit!). My three great passions are: books, coding, and fitness. more »

Don't miss my next post!

Sign up to get my blog posts sent directly to your inbox (plus exclusive store discounts!).

You might like these


  1. I admire people who can code. Personaly I am terrified of this stuff. I have a feeling if I tried touching any code on my site everything would just blow up.

    Great blog btw. First time i see someone who explains wp in such detail.


    Neno recently posted: Dorsoduro hotels
        1. Sorry but that can’t really be done with this plugin. It would involve more/different coding.

  2. I am sorry but don’t get this “ng-image-hover” to work. I have downloaded the plugin and installed it but I don’t find it on the panel. How shall I do to put text to my image and get it to hover when mouse over. I have the latest wordpress.

    Best regards

    1. A most interesting article. Sadly I’m not a coder and don’t have much time to learn so I really appreciate your work and giving the plugin away. I have the same situation as Ulf. I installed the plugin. It’s in the plugin list and activated but it’s nowhere to be found to actually use it.

      1. The instructions for how to use it are in the post. You use a shortcode like this:

        [hover-effect image="image URL here" alt="alt text for the image"]Text you want to appear on hover here.[/hover-effect]

        There are no settings in the plugin.

  3. Hi,

    I am using this for a friend’s site and her products are side by side. When I hover over the book, the next image is still “on top” which makes the hover text unreadable as it’s now behind the image on the right of it.

    Is there a way to change this?

    1. Hi Wonetta,

      Have you tried adding a line in the CSS for z-index? That should bring your hover text to a layer on top of everything if done correctly. Try adding:

      z-index: 10;

      In its own line, just below the “left: 100%” line. Hope it works for you.

  4. An amazing starter for wp plugin development. I simply loved the way you described it. Waiting for more tutorials to come. Do you have a youtube channel, by any chance?

  5. This is great – I was wondering if there’s a way to make it so that the text box is brought to the front when you reveal it? I have a series of photos next to each other in a line on my site, and when you hover over one, the text is hidden behind the next photo. Thank you!

  6. Just found this and I love it …. 😀 but I have a question, can this be done with text and have it hover with an image and text instead? I code but not plugins – is this an easy change?

  7. Thanks for sharing Ashley!
    I’m testing with WP in localhost and what I intended was exactly what is here on the blog in the “Post Comment” ; “Reply”; “Download” buttons etc.
    Image with Text and On Mouseover change the image by a unique color.
    Will it be possible help me please?
    Thank you in advance.

  8. I downloaded and installed the plugin when I tried to use it with shortcode [hover-effect image=”image URL here”]Text you want to appear on hover here.[/hover-effect] after I changed image link and text but it shows nothing, only the image…

  9. First of all thanks for this piece of work. Then a question: I’d like to change the font attributes and the background of the text box. I changed the ,ng-image-hover.css file changing the background from white to black and adding the font-family key to the .ng-image-hover-text class but I obtained no results. What am I doing wrong?

    Thanks again

Recent Posts

    Random Posts