Images with hoverable Overlays
Tags: css, webdesign, ui, webdev
Published: 2019-10-06 10:48:35

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.

### Edit

Added suggestions by [Jonas Linn](https://dev.to/jonaslinn) for improved accessibility.

{% codepen https://codepen.io/mikister/pen/MWWWEBX %}


## The HTML

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

```html
<figure class="card">
    <img class="card__image" alt="Alt text here" src="">
    <figcaption class="card__info"></figcaption>
</figure>
```

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:

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

.card__image {
  display: block;
}

```

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:

```css
.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;
}
```

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:

```css
.image_card {
  border-radius: 20px;
  overflow: hidden;
}
```

and add a drop shadow:

```css
.image_card {
  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
}
```

## 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](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#The_title_attribute) 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:

* [CSS Tricks - A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) - nice reference for css flexbox, useful for creating a linear layout
* [W3Schools - CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp) - nice reference for how css selectors function

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