CSS drop-shadow() Function
The CSS drop-shadow() function adds a shadow that follows the visible shape of an element, including transparent images and irregular outlines.
It is used with the filter property to control a shadow's horizontal offset, vertical offset, blur, and color. Unlike box-shadow, which follows an element's rectangular box, drop-shadow() uses the rendered content's transparency to determine the shadow's shape.
Syntax
filter: drop-shadow(offset-x offset-y);
filter: drop-shadow(offset-x offset-y blur);
filter: drop-shadow(offset-x offset-y blur color);
The function requires two length values for the horizontal and vertical offsets. An optional third length controls blur, and an optional color specifies the shadow color.
For example:
.image {
filter: drop-shadow(5px 5px 8px #666);
}
This places a gray shadow 5 pixels to the right and 5 pixels below the image, with an 8-pixel blur value.
Additional examples:
filter: drop-shadow(5px 5px);
filter: drop-shadow(5px 5px 10px);
filter: drop-shadow(-5px -5px 8px #333);
filter: drop-shadow(0 0 10px red);
filter: drop-shadow(#0066cc 4px 6px 8px);
The color may appear before or after the length values.
The drop-shadow() function returns a CSS filter value and is commonly used with the filter property.
Parameters
The drop-shadow() function accepts two required lengths, one optional blur length, and an optional color.
| Parameter | Description | Required |
|---|---|---|
offset-x |
Moves the shadow horizontally. Positive values move right, and negative values move left. | Yes |
offset-y |
Moves the shadow vertically. Positive values move down, and negative values move up. | Yes |
blur |
Controls the Gaussian blur standard deviation. Must be zero or positive. | No |
color |
Specifies the shadow color. Defaults to the element's current text color. | No |
For example:
filter: drop-shadow(4px 6px 10px rgba(0, 0, 0, 0.4));
The values represent a 4-pixel horizontal offset, a 6-pixel vertical offset, a 10-pixel blur value, and a semi-transparent black shadow.
Unlike box-shadow, the function does not accept a spread radius or the inset keyword.
How It Works
The drop-shadow() function uses the transparency of the rendered element to create its shadow.
The browser creates a shadow from the element's visible pixels, applies the specified offset and blur, and draws the shadow behind the original content.
For example:
.logo {
filter: drop-shadow(6px 6px 8px rgba(0, 0, 0, 0.4));
}
If the logo has a transparent background, the shadow follows the visible logo instead of the rectangular image boundaries.
When the element has an opaque rectangular background, the shadow generally follows that rectangle.
The filter is applied to the rendered element as a whole, including its visible content and descendants.
Shadow Offsets
The first two length values control the shadow's horizontal and vertical position.
| Value | Effect |
|---|---|
drop-shadow(5px 5px) |
Moves the shadow right and down. |
drop-shadow(-5px 5px) |
Moves the shadow left and down. |
drop-shadow(5px -5px) |
Moves the shadow right and up. |
drop-shadow(-5px -5px) |
Moves the shadow left and up. |
drop-shadow(0 0) |
Places the shadow directly behind the visible content. |
For example:
.shadow-right {
filter: drop-shadow(8px 0 4px #666);
}
.shadow-left {
filter: drop-shadow(-8px 0 4px #666);
}
.shadow-bottom {
filter: drop-shadow(0 8px 4px #666);
}
.shadow-top {
filter: drop-shadow(0 -8px 4px #666);
}
Zero offsets are useful for creating a glow or an evenly distributed shadow around the visible shape.
Blur
The optional third length controls the softness of the shadow.
For example:
filter: drop-shadow(5px 5px 0 #333);
filter: drop-shadow(5px 5px 4px #333);
filter: drop-shadow(5px 5px 12px #333);
A blur value of 0 produces a sharp shadow. Larger values create softer shadows that extend farther from the original shape.
The blur value represents the standard deviation of a Gaussian blur, not a fixed distance that the shadow extends.
Negative blur values are invalid:
filter: drop-shadow(5px 5px -4px #333);
Use zero or a positive length instead.
Shadow Color
The optional color value controls the shadow's appearance.
For example:
filter: drop-shadow(4px 4px 6px black);
filter: drop-shadow(4px 4px 6px #0066cc);
filter: drop-shadow(4px 4px 6px rgb(255 0 0 / 50%));
Transparent colors are useful for creating softer, more natural shadows.
For example:
.logo {
filter: drop-shadow(4px 6px 8px rgba(0, 0, 0, 0.3));
}
When no color is specified, the function uses the element's current color value.
For example:
.icon {
color: #0066cc;
filter: drop-shadow(4px 4px 5px);
}
The shadow uses the blue text color because no separate shadow color was provided.
Transparent Images
Transparent PNG, WebP, and SVG images are common uses for drop-shadow().
For example:
.logo {
filter: drop-shadow(6px 8px 10px rgba(0, 0, 0, 0.35));
}
When applied to an image with transparent areas, the shadow follows its visible pixels.
This is particularly useful for logos, icons, illustrations, and product images that do not have rectangular backgrounds.
For example:
<img src="logo.png" class="logo" alt="Company logo">
If the image contains transparent padding, the shadow is based on the visible artwork rather than the transparent padding.
An image with a solid rectangular background will produce a rectangular shadow because the background pixels are opaque.
Multiple Shadows
Multiple drop-shadow() functions can be applied to the same element.
For example:
.logo {
filter: drop-shadow(4px 4px 3px #0066cc) drop-shadow(-4px -4px 3px #cc3399);
}
The first function creates a blue shadow, and the second adds a pink shadow.
Unlike comma-separated box-shadow values, multiple filter functions are separated by spaces.
For example:
.icon {
filter: drop-shadow(2px 2px 0 red) drop-shadow(-2px -2px 0 blue);
}
Filters are applied in order. Each subsequent function processes the output of the preceding function, including any shadows already created.
This means multiple drop-shadow() functions can produce different results from independently layered shadows.
Combining Filters
The drop-shadow() function can be combined with other CSS filter functions.
For example:
.image {
filter: grayscale(100%) drop-shadow(5px 5px 8px #666);
}
This converts the image to grayscale and then adds a gray drop shadow.
Another example:
.image {
filter: brightness(110%) contrast(120%) drop-shadow(4px 6px 8px #333);
}
The browser applies each filter in the order listed.
Changing the order can change the result:
filter: drop-shadow(5px 5px 8px red) grayscale(100%);
filter: grayscale(100%) drop-shadow(5px 5px 8px red);
In the first declaration, grayscale also affects the red shadow. In the second, the red shadow is added after the image has been converted to grayscale.
Example
This example demonstrates three drop shadows with different offsets and blur values.
HTML:
<div class="drop-shadow-demo">
<div class="drop-shadow-item">
<div class="drop-shadow-wrapper shadow-soft">
<div class="drop-shadow-shape"></div>
</div>
<span>Soft Shadow</span>
</div>
<div class="drop-shadow-item">
<div class="drop-shadow-wrapper shadow-sharp">
<div class="drop-shadow-shape"></div>
</div>
<span>Sharp Shadow</span>
</div>
<div class="drop-shadow-item">
<div class="drop-shadow-wrapper shadow-glow">
<div class="drop-shadow-shape"></div>
</div>
<span>Glow Effect</span>
</div>
</div>
CSS:
.drop-shadow-demo {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 25px;
padding: 25px 10px;
}
.drop-shadow-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
font-size: 13px;
}
.drop-shadow-wrapper {
width: 65px;
height: 65px;
}
.drop-shadow-shape {
width: 65px;
height: 65px;
background-color: #0066cc;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.shadow-soft {
filter: drop-shadow(6px 6px 6px rgba(0, 0, 0, 0.5));
}
.shadow-sharp {
filter: drop-shadow(6px 6px 0 #333);
}
.shadow-glow {
filter: drop-shadow(0 0 8px #0066cc);
}
Each triangle uses the same base shape. The different filter values control the appearance of its shadow.
Applying the filters to the outer wrappers prevents the triangle's clip-path from clipping the shadows.
Shape Example
This example compares box-shadow and drop-shadow() on a triangular element.
HTML:
<div class="shadow-compare">
<div class="shadow-compare-item">
<div class="shadow-compare-box"></div>
<span>box-shadow</span>
</div>
<div class="shadow-compare-item">
<div class="shadow-compare-filter">
<div class="shadow-compare-triangle"></div>
</div>
<span>drop-shadow()</span>
</div>
</div>
CSS:
.shadow-compare {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 40px;
padding: 25px 10px;
}
.shadow-compare-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
font-size: 13px;
}
.shadow-compare-box {
width: 80px;
height: 80px;
background-color: #0066cc;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
box-shadow: 6px 6px 8px #666;
}
.shadow-compare-filter {
filter: drop-shadow(6px 6px 8px #666);
}
.shadow-compare-triangle {
width: 80px;
height: 80px;
background-color: #0066cc;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
The box-shadow effect is clipped by the triangle's clip-path, so its shadow is not visible. The drop-shadow() filter is applied to the outer wrapper, allowing the shadow to follow the visible triangular shape.
This demonstrates why a filter on a wrapper can be useful when creating shadows for clipped elements.
drop-shadow() vs. box-shadow
Both techniques create shadows, but they use different methods to determine the shadow's shape.
| Feature | drop-shadow() | box-shadow |
|---|---|---|
| Shadow shape | Follows visible pixels and transparency. | Follows the element's box shape. |
| Transparent images | Follows the visible artwork. | Uses the image element's box. |
| Spread radius | Not supported. | Supported. |
| Inset shadow | Not supported. | Supported. |
| Multiple shadows | Multiple filter functions. | Comma-separated shadow values. |
| CSS usage | filter: drop-shadow(...) |
box-shadow: ... |
For example:
.image {
filter: drop-shadow(5px 5px 8px #666);
}
.card {
box-shadow: 5px 5px 8px #666;
}
Use drop-shadow() for transparent images and irregular shapes. Use box-shadow for cards, panels, and other elements that need shadows around their boxes.
Transitions and Animations
The drop-shadow() function can be used in CSS transitions and animations.
For example:
.icon {
filter: drop-shadow(2px 2px 3px rgba(0, 0, 0, 0.2));
transition: filter 0.3s ease;
}
.icon:hover {
filter: drop-shadow(6px 6px 10px rgba(0, 0, 0, 0.5));
}
The shadow becomes larger, softer, and darker when the element is hovered.
For keyboard-accessible interactive elements, include a focus state:
.button:hover,
.button:focus-visible {
filter: drop-shadow(4px 4px 6px rgba(0, 0, 0, 0.4));
}
To reduce motion for users who request it:
@media (prefers-reduced-motion: reduce) {
.icon {
transition: none;
}
}
Animating filters can require additional rendering work, especially when applied to large images or elements with complex content.
Common Uses
The drop-shadow() function is useful for adding depth to visible shapes without relying on rectangular shadows.
| Use | Description |
|---|---|
| Logos | Add shadows that follow transparent logo artwork. |
| Icons | Create subtle shadows or glow effects around icons. |
| Product images | Add depth to isolated products on transparent backgrounds. |
| SVG graphics | Apply shadows to irregular vector shapes. |
| Clipped shapes | Create shadows around shapes made with clip-path. |
| Interactive elements | Adjust shadows during hover, focus, and animation states. |
| Glow effects | Use zero offsets and colored blur to create a glow. |
For example:
.product-image {
filter: drop-shadow(8px 10px 12px rgba(0, 0, 0, 0.25));
}
The shadow follows the product's visible silhouette when the source image has transparent areas.
Limitations
The drop-shadow() function has several important rules and limitations.
- It requires two length values for the horizontal and vertical offsets.
- The optional blur value cannot be negative.
- Spread radius values are not supported.
- The
insetkeyword is not supported. - The shadow follows rendered transparency rather than the element's rectangular box.
- Applying a filter to an element with an opaque background generally produces a shadow around that background.
- Large blur values and multiple filters may increase rendering costs.
- Filters do not increase the element's layout dimensions, so shadows may be clipped by surrounding containers.
For example, this is valid:
filter: drop-shadow(5px 5px 10px #333);
The following is invalid because it includes a spread radius:
filter: drop-shadow(5px 5px 10px 4px #333);
The following is also invalid because inset is not supported:
filter: drop-shadow(inset 5px 5px 10px #333);
For inset shadows or spread control, use the box-shadow property instead.
Browser Support
The CSS drop-shadow() function is Baseline Widely available. It has been supported across major browser engines since September 2016.
It works in current versions of Chrome, Edge, Firefox, Safari, and other modern browsers.
For example:
.logo {
filter: drop-shadow(5px 5px 8px rgba(0, 0, 0, 0.35));
}
For current compatibility information, visit Can I Use? .
Specifications
The drop-shadow() function is defined in the Filter Effects Module Level 1 .
The specification defines how shadow offsets, blur, and color are applied to the rendered input image.
Related CSS features include filter, box-shadow, blur(), opacity(), and clip-path.
