Skip to content

RESOURCES / BLOG

How can CSS drop-shadow filters add depth, realism, and emphasis to UI components?

CSS featured image

UI threads often debate the “right” way to add depth: box-shadow for cards, filter-based shadows for icons, or both. Designers want realistic elevation and crisp edges, while engineers want performance that holds up under scroll and animations. 

I see a lot of designs using CSS filter: drop-shadow(…) instead of box-shadow. How can CSS drop-shadow filters add depth, realism, and emphasis to UI components? When should I prefer drop-shadow over box-shadow, and what are some reliable recipes for buttons, icons with transparency, avatars, and floating cards? Code examples appreciated.

The key difference: box-shadow renders a shadow based on the element’s box rectangle, while filter: drop-shadow(…) traces the alpha shape of the rendered pixels. That makes drop-shadow ideal for non-rectangular content, like transparent PNGs or inline SVGs, and for icons or avatars where you want a realistic contour.

  • Use drop-shadow for images with transparency, vector icons, and irregular shapes. It follows the silhouette, so circular avatars, logos, and SVGs look naturally lifted.
  • Use box-shadow for rectangular UI surfaces like cards, modals, menus, and sheets where elevation is about the container rather than the content.
  • Combine them when needed: box-shadow for card elevation, drop-shadow for the non-rectangular content inside.
/* drop-shadow offsets, blur, and color: */
.element {
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.2));
}

/* Multiple layered shadows for more natural falloff */
.element--elevated {
  filter:
    drop-shadow(0 1px  2px rgba(0, 0, 0, 0.12))
    drop-shadow(0 6px 12px rgba(0, 0, 0, 0.16));
}Code language: CSS (css)
.avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.18));
}Code language: CSS (css)

Because drop-shadow traces the image’s alpha, you avoid the “square glow” you often get with box-shadow on images.

.icon {
  display: inline-block;
  width: 24px;
  height: 24px;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}Code language: CSS (css)

Inline SVGs render vector shapes with transparency, so the shadow hugs the glyphs rather than a rectangular box.

.card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,.08); /* base elevation */
  transition: transform .18s ease, filter .18s ease, box-shadow .18s ease;
}
.card:hover {
  transform: translateY(-2px);
  /* Keep a subtle box-shadow and add a soft silhouette from inner content */
  box-shadow: 0 4px 12px rgba(0,0,0,.12);
  filter: drop-shadow(0 8px 20px rgba(0,0,0,.12));
}Code language: CSS (css)
.btn:focus-visible {
  outline: none;
  /* Colored glow that respects the element shape */
  filter: drop-shadow(0 0 8px rgba(0, 120, 255, 0.45));
}Code language: CSS (css)

Drop shadows look best when your source assets have an alpha channel. Review which file types support transparency and how to choose the right one in this guide on transparent image file types. As a rule of thumb, prefer PNG or WebP for icons and logos that need transparency. If you are deciding between common formats, see JPEG vs PNG comparisons for pros and cons.

To keep UI snappy, reduce asset weight. When appropriate, convert PNGs to modern formats for better compression using a tool like PNG to WebP. Smaller payloads make animated hover effects and scrolling smoother.

  • Layer shadows with increasing blur and decreasing opacity to mimic natural light falloff.
  • Use cooler and darker tints for deep elevations and slightly warmer tints for surface contact shadows.
  • Avoid 0 px y-offset unless you want a glow. Small positive y-offsets read as elevation.
  • Animate elevation on interaction with small changes to blur and y-offset rather than huge opacity jumps.
  • Filters can trigger extra rendering work. Reserve heavy multi-layered drop shadows for key components, not for hundreds of list items.
  • Prefer fewer layers with moderate blurs. Large blurs on many elements can be costly.
  • Combine with transform-based animations; avoid animating filter blur across large areas if you can.

If you manage many icons and avatars, deliver them in a size and format that suits your UI and preserves alpha. You can also enhance visual quality at source. 

Example with Cloudinary delivery that preserves transparency and picks an efficient format automatically:

<img
  class="avatar"
  src="https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_128/sample.png"
  alt="Team member"
/>

.avatar {
  border-radius: 50%;
  filter: drop-shadow(0 10px 24px rgba(0,0,0,.18));
}Code language: JavaScript (javascript)

Using automatic format and quality keeps files small while retaining the alpha channel that makes drop-shadow look realistic. You can apply the same idea to SVG icons or logos and style them with the CSS recipes above.

  • Use filter: drop-shadow for non-rectangular content and assets with transparency. Use box-shadow for container elevation.
  • Layer subtle shadows for natural depth and animate hover states with small changes in blur and offset.
  • Deliver lightweight transparent assets for best performance. Consider PNG or WebP depending on your needs.
  • At scale, use a media pipeline to output right-sized, alpha-preserving assets and then style with CSS drop-shadow in the UI.

Ready to optimize image delivery and build visually rich UI at scale? Sign up for a free Cloudinary account and start transforming, optimizing, and delivering your assets today.

Start Using Cloudinary

Sign up for our free plan and start creating stunning visual experiences in minutes.

Sign Up for Free