drop-shadow()

Gabriel Shoyombo on Updated on
##description##
Ad
`, } ); } })();

The CSS drop-shadow() function applies a shadow effect to an element. Specifically, it creates a shadow around the element’s content shape, respecting its outline and transparency, so it comes in handy when we need a shadow effect around an irregularly-shaped element.

It is used with the filter and backdrop-filter properties, which allows us to apply varying visual effects, like blur()grayscale()sepia(), and yes, drop-shadow().

div {
  background-color: #cdcdcd;
  filter: drop-shadow(#301934 20px 10px 4px);
}

The drop-shadow() function is defined in the Filter Effects Module 1 specification.

Syntax

The drop-shadow() syntax is similar to the box-shadow property you probably know about, but it only takes three length arguments (instead of four) and one color argument:

filter: drop-shadow(5px 5px 5px #cdcdcd);

Formally, it is declared as:

<drop-shadow()> = drop-shadow( [ <color>? && <length>{2,3} ] )

Arguments

/* It can take a color along the two offsets */
filter: drop-shadow(#301934 20px 10px);
filter: drop-shadow(#301934 12px -12px);
filter: drop-shadow(#301934 -15px -5px);

/* We can add a blur radius */
filter: drop-shadow(#301934 15px 15px 5px);

/* The color can be at the end */
filter: drop-shadow(20px 10px 5px #301934);

The drop-shadow() function takes two parameters, which we can translate into two to four arguments. Let’s see how they look:

The <length> parameter can take two or three values. If two values are taken, the browser uses them to define the <offset-x> and <offset-y> positions. The blur only comes in when all three lengths are used.

Basic usage

All we do is declare the filter property on an element and set the drop-shadow() function on it:

svg {
  filter: drop-shadow(0 30px 30px #333);
}

Example: Layering shadows

You might already know that we can set multiple shadows on the box-shadow property for a longer, smoother looking shadow effect. All it takes is separating each shadow with a comma:

.box {
  box-shadow:
    0 2.8px 2.2px rgb(0 0 0 / 0.034),
    0 6.7px 5.3px rgb(0 0 0 / 0.048),
    0 12.5px 10px rgb(0 0 0 / 0.06),
    0 22.3px 17.9px rgb(0 0 0 / 0.072),
    0 41.8px 33.4px rgb(0 0 0 / 0.086),
    0 100px 80px rgb(0 0 0 / 0.12);
}

Well, we can do the same with the drop-shadow() filter function, only without the commas:

.box {
  filter:
    drop-shadow(0 2.8px 2.2px rgb(0 0 0 / 0.034))
    drop-shadow(0 6.7px 5.3px rgb(0 0 0 / 0.048))
    drop-shadow(0 12.5px 10px rgb(0 0 0 / 0.06))
    drop-shadow(0 22.3px 17.9px rgb(0 0 0 / 0.072))
    drop-shadow(0 41.8px 33.4px rgb(0 0 0 / 0.086));
}

Here’s another example where you can toggle the shadow on and off:

Example: Retro SVG effect

This is a visual style that mimics old-school graphic designs, particularly from the 1970s and 80s. It uses the same layering technique we looked at earlier:

.retro-shadow {
  filter:
    drop-shadow(4px 4px 0px #ef4444)
    drop-shadow(8px 8px 0px #3b82f6)
    drop-shadow(12px 12px 0px #22c55e);
}

Notice that I’m setting the blur radius value to 0 in each drop shadow. This means the shadows don’t spread out but instead have sharp edges to them. The result is a sorta retro-looking design touch:

Example: Animating drop-shadow()

Kevin Powell built a beating heart using the steps() function in one of his YouTube shorts, and I replicated it in the steps() entry. Here, I am trying out the heartbeat animation again, but this time with drop-shadow() radius blur to create a pulsing beat.

.pulsing-drop-shadow {
  animation: pulse-drop-glow 2s infinite alternate;
}

@keyframes pulse-drop-glow {
  from {
    filter: drop-shadow(0 0 2px #ec4899);
  }
  to {
    filter: drop-shadow(0 0 15px #ec4899);
  }
}

Comparing drop-shadow() to box-shadow and text-shadow

For those of you keeping count, there are three ways to set shadows on things in CSS:

Why do we need all three? Well, first off, neither drop-shadow() nor box-shadow support text content. We need the text-shadow property specifically for that task.

But what about the other two? There’s a subtle but very important difference between drop-shadow and box-shadow and the clue is the “box” in box-shadow. The property merely applies a shadow around an element’s border box, which is always a square/rectangular shape, even if the element’s visual shape isn’t boxy. A classic example is setting box-shadow on an image:

The difference between box-shadow and filter: drop-shadow() really boils down to the CSS box model. One sees it and the other disregards it. See how drop-shadow() traces around the image’s transparent parts:

Another key difference is that the spread of the radius for drop-shadow() is calculated differently than box-shadow, and even that of text-shadow. That means that the spread radius you might specify in box-shadow is not one-to-one with the default spread value for drop-shadow, so the two are not equal replacements of one another in some cases.

How about a table that compares the three types of shadows side-by-side:

drop-shadow()box-shadowtext-shadow
How it worksCreates a shadow around the element’s alpha.Creates a shadow around the element’s rectangular box.Creates a shadow around text elements.
Spread radius?NoYes (optional)No
Blur radius?YesYesYes
UsesAny shape of elementPerfect for rectangular and square elementsText elements
Hardware accelerationIn browsers that support itNoNo

Specification

The CSS drop-shadow() function is defined in the Filter Effects Module 1 specification, which is currently in Editor’s Draft.

Browser support

The CSS drop-shadow() filter function is supported by all major browsers.

References