Main Menu

How to CSS-Only Overlays Effect with Box-Shadow

Content overlays are a prominent part of modern web design. They help you hide an element on a web page, and later – with the user’s approval – reveal it, and display extra information or controls, such as buttons behind it.

A typical overlay is semi-transparent, with a solid background color (usually black), and there’s some text or buttons on it for users to see or interact with. After the interaction (clicking or hovering) occurs, the overlay gets removed and reveals the content beneath it.

In this article, we’ll have a look at how to add colored overlay to images by using pure CSS. You can see the final result on the demo below. Hover the images to make the overlays reveal the pokemons. Although this post discusses images, the technique it presents can be safely applied to other content types (such as text blocks) as well.

Avoid Adding Extra HTML Elements

Overlays are frequently created by positioning an extra HTML element with an opacity value less than 1 right above the element to be covered. The problem is that this technique involves the usage of an extra element (or pseudo-element) for the overlay.

If you aren’t an HTML size pedantic, having an extra element for overlay is probably not a big deal, as most likely it won’t tax the bandwidth of any network that much. However having separate style rules for elements & their overlays still harms CSS readability and maintainability.

To keep your code in order, and not to mess your HTML outline up, it’s a better choice to use a CSS-only solution.

Create Overlay with box-shadow

So how can you actually create a CSS-only overlay? With the help of the box-shadow CSS property. The box-shadow is perfect for this job, since what is an overlay but a dark shadow cast over an element?

The box-shadow has a property value called inset, which causes the shadow to appear inwards of the frame of the box.

An inset box-shadow with a shadow size half or more than half of the width and height of the element, creates a shadow that covers the entire element.

Create the Code for the Demo

Our demo will show the images and names of different pokemons. Here we’ll only create the code for Bulbasaur, the first pokemon in the demo, as the others are made the same way (on Codepen you can check out the code for them as well).

HTML

For the HTML, we only need to create a box to which we’ll add everything else with CSS.

<div id="bulbasaur" class="pokemon"></div>

CSS

In the CSS below, the .pokemon elements display the pokemon images, and the .pokemon::after pseudo-elements carry the name of the pokemon.

Since the box-shadow property can take multiple values in order to render multiple shadows, besides the overlay shadow, I also added other shadows of grey to the .pokemon and .pokemon:hover elements for aesthetics.

When the .pokemon elements are hovered, their box-shadow need to change to reveal the image behind.

You can see that the .pokemon:hover selector gets a new box-shadow that removes the overlay, and the .pokemon:hover::after selector hides the name of the pokemon by using the opacity property.

You might have also noticed the absence of color values in the overlay box-shadows in the .pokemon and .pokemon:hover style rules. The overlay box-shadow color of the individual pokemons need to be specified in their own seperate style rules, as they’re all different from each other.

As box-shadowdoesn’t have any longhand property, you can’t set its shadow color individually with something like, box-shadow-color; instead – we use the color property.

By default, when you give a value for the color property, that value is applied for the border, the outline and the box-shadow colors as well. So, you can simply use the color property to add color to box-shadow.