Images and text overlays in HTML/CSS

21 May 2018

Hello,

Here is a very simple tutorial to design image overlays in HTML and CSS only.

Indeed, who has never wanted to quickly position a text over an image? Then change it on mouse hover or even display an alternate image?

The code provided in this article may apply to any website. Simply integrate the HTML code on a page and the CSS code into your stylesheet.

You can find different ways to do it on the internet, but I wanted to synthesize everything I found to extract a minimal and above all clean solution.

What is an image text overlay?

For me, an overlay is just a layer put on top of another. In HTML, it means that it is out of the flow, because it has to be positionned over another element, which is not possible with the default behaviour.

Note: I’m not talking here about text over a background image, which is standard in HTML, but text over an image element (the infamous img tag).

Simple text overlay with no hover

Alt text

Image + text
NO HOVER

Overlay with background and text change on hover

Alt text

Image + text
ORIGINAL
Background + text
HOVER

Overlay with text and image change on hover

Alt text

Image + text
ORIGINAL
Texte alternatif hover

Image + text
HOVER

HTML code: original content and overlay

Content structure

The overlay-image class container encapsulates all the necessary structure:

  • original image,
  • original overlay text block,
  • image/text overlay block displayed on mouse hover.

On a page written without a page builder (HTML page or simple WordPress theme), for instance like this article, it is essential to define it in order to properly include original content and overlay within the page.

With a builder, it can be replaced by an existing container block (for example it could be the Divi “code” module, to which we simply add the overlay-image class).

The code below also includes encapsulating link tags to make images clickable, but you can remove them if not needed.

The HTML code

/* Simple overlay */
<div class="overlay-image"><a href="LINK_URL">
 <img class="image" src="IMAGE" alt="Alt text" />
 <div class="text">Image + text
  NO HOVER</div>
</a></div>
/* Color background and text overlay on hover */
<div class="overlay-image"><a href="LINK_URL">
 <img class="image" src="IMAGE" alt="Alt text" />
 <div class="normal">
  <div class="text">Image + text
   ORIGINAL</div>
 </div>
 <div class="hover">
  <div class="text">Background + text
   HOVER</div>
 </div>
</a></div>
/* Image and text overlay on hover */
<div class="overlay-image"><a href="LINK_URL">
 <img class="image" src="ORIGINAL_IMAGE" alt="Alt text" />
 <div class="normal">
  <div class="text">Image + text
   ORIGINAL</div>
 </div>
 <div class="hover">
  <img class="image" src="OVERLAY_IMAGE" alt="Alt text hover" />
  <div class="text">Image + text
   HOVER</div>
 </div>
</a></div>

CSS code: text overlay and text/image change on hover

The code below is to be included in your styles definition:

  • style.css file included in your HTML file if you work directly in HTML,
  • style.css file of your child theme if you work with WordPress,
  • or your Divi page options if the mechanism is only used at a specific location.

How to display the original or simple text overlay?

The overlay-image class allows you to set the global container when not using a page builder. In this article, I replaced the “width: 100%;” by “width: 80% margin: auto;” to add margins.

Important note: The image-overlay container MUST be “positioned” itself (here relative) in order to position its own elements.

Original image and text overlay are defined by  .overlay-image .image and  .overlay-image .text specifiers:

  • the image fills all available space,
  • the text is centered on the image using an absolute “positioning” on the container block and a X-Y translation (a CSS classic).

How to display the new overlay on hover?

The hover overlay is materialized by .overlay-image .hover, and “positioned” in absolute to occupy the entire surface of the container including original image and text (100% width and height).

When the mouse hovers, its opacity changes from 0 to 1 with a smooth transition to make it appear over the original div.

To overlay a text block only (without image), you must first hide the original text because the new image is not there to do so.

The CSS code

I tried to factorize the code to make it simple, readable, compact and easily usable. To do so, I divided it into three parts that you can pick according to your needs.

The first part is common to all three kinds of previous overlays and this is the only one needed for a simple text overlay:

/********* Simple or original overlay *******/

/* Main container */
.overlay-image {
 position: relative;
 width: 100%;
}

/* Original image */
.overlay-image .image {
 display: block;
 width: 100%;
 height: auto;
}

/* Original text overlay */
.overlay-image .text {
 color: #fff;
 font-size: 30px;
 line-height: 1.5em;
 text-shadow: 2px 2px 2px #000;
 text-align: center;
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 width: 100%;
}

This part is needed by both overlays on hover:

/********* Overlay on hover *******/

/* New overlay on hover */
.overlay-image .hover {
 position: absolute;
 top: 0;
 height: 100%;
 width: 100%;
 opacity: 0;
 transition: .5s ease;
}

/* New overlay appearance on hover */
.overlay-image:hover .hover {
 opacity: 1;
}

This last part in only needed for background + text overlay on hover:

/********* Background and text only overlay on hover *******/

.overlay-image .normal {
 transition: .5s ease;
}
.overlay-image:hover .normal {
 opacity: 0;
}
.overlay-image .hover {
 background-color: rgba(0,0,0,0.5);
}

Conclusion

As you can see, overlays are not technically very difficult… It’s a shame that the mechanism is not part of all WordPress themes on the marketplace!

However, pay attention to the HTML code insertion in your WordPress editor or theme builder.

Personally, I had a bad surprise writing this article when I switched from “Text” to “Visual” tab in the editor, because WordPress reformats the HTML code. And it doesn’t do it well: moving the </a> tags, adding </p>, removing </div>… In short, it breaks everything! The only solution I found (while waiting to patch the bad CMS!) is to properly reformat the HTML code via the “Text” tab before saving for the last time, or just work in text mode all the time 🙁