DEV Community

Cover image for Images with hoverable Overlays
Milan Radojević
Milan Radojević

Posted on • Updated on

Images with hoverable Overlays

An image is worth a 1000 words, but sometimes you want to use both. Here's a short little tutorial on how to add info overlays to image cards when you hover over them.


Added suggestions by Jonas Linn for improved accessibility.


Let's look first at how to structure our html:

<figure class="card">
    <img class="card__image" alt="Alt text here" src="">
    <figcaption class="card__info"></figcaption>
Enter fullscreen mode Exit fullscreen mode

We have a figure element with class card which will hold everything.

Add image link to src, also be sure to add alt text (this will be read by screen reader software).

figcaption is the element which will hold the content of our overlay. You can add other pictures there, tables maybe, your imagination is the limit.

Positioning the Image and the Overlay

Now let's switch to css to see how we positioned everything:

.card > * {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

.card__image {
  display: block;

Enter fullscreen mode Exit fullscreen mode

The first selector will select any child of inside the card. We just set position to absolute so that we can stack element over each other, and have them cover their parent.

One important thing to note is that the parent element (.card) should have position: relative; set or the image and overlay will position in the top left corner of the page (or the top left corner of first element, going up the html tree, that has position property set).

With the second selector we override the default display: inline for images.

Reveal Overlay on hover

Now for the overlay:

.card__info {
  opacity: 0;
  transition: opacity 300ms ease;

  color: white;
  background-color: rgba(0, 0, 0, 0.5);

.card:hover .card__info,
.card:focus-within .card__info {
  opacity: 1;
Enter fullscreen mode Exit fullscreen mode

We set the default opacity on our overlay to zero, this means that it's still there, just invisible. But with the second selector we tell the browser to change that opacity back to 100% when we hover over the image card.

If we don't want to have the overlay just instantly appear, we can slowly turn up the opacity by setting the transition property. It will make any change to opacity happen over a certain time period, in this case 300 milliseconds.

And we also want a half transparent (opaque) background for the overlay. We do that with rgba(), it accepts four parameters, red value of a color, green value, blue value, and alpha value (basically opacity of the color).

Finishing touches

This isn't required but I like to round off my cards:

.image_card {
  border-radius: 20px;
  overflow: hidden;
Enter fullscreen mode Exit fullscreen mode

and add a drop shadow:

.image_card {
  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
Enter fullscreen mode Exit fullscreen mode

A few words about accessibility and sematics

Background images should only be used for decorative purposes, because screen readers can't access them. So in most cases it is recommended to use an img tag.

Images should be wrapped inside of figure tag, and their accompanying description (in this case the overlay) should be wrapped with figcaption tag. Read MDN - img element second paragraph in the "The title attribute" section.

Read More

Here are some links to article/pages with topics that are relevant to stuff used in here:

I hope you found this useful. If you have anything to suggest or just wanna say something please do.

Top comments (2)

jonaslinn profile image
Jonas Linn

Hey Milan, nice post!

A few hints regarding semantics and accessibility. There are two html elements that are perfect for your case: <figure> and <figcaption>.

It is just a quick fork, but it is now accessible via keyboard. Screenreaders will still read it, as it's only hidden with the opacity property.

mikister profile image
Milan Radojević • Edited

Thanks for the suggestion, I'm not too knowledgeable when it comes to accessibility so I appreciate the tip. I'll be sure to edit the article to incorporate it.

Edit: And done, I added the changes.