Box Shadow Gradients

- (6 min read)

While the box-shadow CSS property doesn't have support for gradients, I'm going to show you a neat trick you can use to mimic the effect by stacking absolutely positioned layers.

The box-shadow CSS property was first proposed in 2005, and the web embraced it with open arms. It added depth to a medium that was sorely lacking it. Seventeen years later, its use has grown to be used in almost every layout in some capacity. The most recent trend is layering multiple shadows to create a softer, more realistic effect, and more recently has been used as a way to add a soft glow to elements to really spice them up. The technique in this tutorial involves applying a linear gradient to an element situated underneath another and adding blur to achieve a soft, shadow-like appearance. This works best with small, self-contained elements that you want to pop out of the page, but still be anchored to its position on the page.

An example of the technique in use.

The basic structure

There are only three divs for this process: a wrapper that will set the bounds, the shadow element that will contain the gradient, and the box we want to sit on top that will contain our content.

<div class="wrapper">
    <div class="shadow"></div>
    <div class="box">
	  <h1>Content</h1>
        <p>stuff</p>
    </div>
</div>

For the css, we need to apply position:absolute to the shadow element in order to "float" it inside the wrapper by taking it out of the wrapper context. Because the wrapper is relatively positioned, it becomes the bounds for any positioned elements inside it, which we take advantage of by applying width: 100%; height: 100%; in order to fill out to the wrapper dimensions. Any positioned element needs to have at least one top, right, bottom, or left to be placed. And because I hate ambiguity, I like to set two values. The box element will also need to have position:relative; applied to it to keep it above the shadow in the stacking context.

.wrapper {
	position: relative;
}

.shadow {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.box {
	position: relative;
}

The result is the shadow element occupying the same space as the box element inside their parent wrapper. Because the box element comes after the shadow element in the html (and is in the same stacking context after being relatively positioned), it appears on top. We can change the order by either changing their order in the html, or by applying a z-index to either the box element or the shadow element, as z-indexes can be applied to positioned elements (ones whose position is other than the default static).

The shadow element is hidden below the box element.

Setting up the shadow element

It's time to start styling the shadow element. The goal here is to make it look like a multi-colored shadow, so we'll need to set the color, the blur amount, and the opacity. The color can be achieved by using a linear-gradient css property. The blur property is a filter function and the amount applied is a length value that has a similar effect as the blur-radius in a normal box-shadow property. Because we want this to be subtle, we lower the opacity to 20%, and give it a generous border-radius to give it a more diffused look.

.wrapper {
    padding: 2rem;
}

.shadow {
	background: linear-gradient(135deg, rgba(130,242,232,1) 0%,rgba(244,48,130,1) 100%);
	filter: blur(10px);
	opacity: 0.2;
	border-radius: 2rem;
}

Adding some padding to the wrapper will shrink the available space the box can grow to fill, but will give our shadow the room it needs to shine. I went with some vaporwave colors because they look cool and I also added a generous border-radius to diffuse the shape a bit. The linear-gradient is set at 135 degrees rather than 120 because the sides are where we want the most color. In the example, you can see that some colors will be more noticeable than others, so take that into consideration.

Because of the padding in the wrapper, we just see the edges of the shadow element, giving the box a subtle glow effect.

Add some depth

The final step is to add some depth with a box-shadow and some content in the box element. When using the box-shadow property for shadows it's been good practice to use multiple shadows in recent years as this gives a more realistic look. In this example I'm using two shadows: one close up for the shadow we're familiar with, and a softer one that reaches further out to imitate a refractive shadow.

.box {
	box-shadow: 
		rgba(0, 0, 0, 0.1) 0px 20px 25px -5px, 
		rgba(0, 0, 0, 0.04) 0px 10px 10px -5px;
	border-radius: 8px;
}

Here is the finished effect:

See the Pen blog-box-shadow-gradient by Michael Royer (@m-royer) on CodePen.

Adding more details like borders and more complete content will make this effect look better. So get out there and start experimenting!