Skip to content

CSS Box Shadow: A Complete Guide with Examples

The CSS box-shadow property is one of the most versatile tools for adding depth, dimension and visual hierarchy to your designs. Whether you need a subtle card elevation, a glowing neon border or a realistic layered shadow, box-shadow can handle it all. In this guide, we will break down the syntax, walk through practical examples and cover performance best practices.

Box-Shadow Syntax

The box-shadow property accepts one or more shadow values separated by commas. Each shadow value follows this structure:

box-shadow: [inset] offset-x offset-y blur-radius spread-radius color;
  • offset-x moves the shadow horizontally. Positive values go right, negative values go left.
  • offset-y moves the shadow vertically. Positive values go down, negative values go up.
  • blur-radius (optional, default 0) controls how soft the shadow edge is. Higher values create a more diffused shadow.
  • spread-radius (optional, default 0) expands or contracts the shadow. Positive values make the shadow larger, negative values make it smaller.
  • color sets the shadow color. Using rgba or hsla with opacity is recommended for natural-looking shadows.
  • inset (optional keyword) places the shadow inside the element instead of outside.

Basic Shadow Examples

A simple shadow with a slight vertical offset and blur creates a clean card elevation effect. This is the most common pattern for cards, modals and dropdowns:

/* Subtle card shadow */

box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

/* Medium elevation */

box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);

/* Strong elevation */

box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);

Notice the pattern. As you increase the offset-y and blur-radius, the element appears to float higher above the surface. Keeping the offset-x at 0 simulates light coming from directly above, which feels most natural.

Multiple Shadows for Realistic Depth

Real-world shadows are not a single uniform layer. They are a combination of a sharp, close shadow and a soft, diffused one. You can stack multiple box-shadow values separated by commas to achieve realistic depth:

box-shadow:

0 1px 2px rgba(0, 0, 0, 0.07),

0 4px 8px rgba(0, 0, 0, 0.07),

0 12px 24px rgba(0, 0, 0, 0.1);

This layered approach is used by design systems like Material Design and Tailwind CSS. The first shadow adds a crisp edge, the second creates mid-range depth and the third provides ambient softness. Together they look far more natural than a single large shadow.

Inset Shadows

Adding the inset keyword places the shadow inside the element. This is useful for creating pressed or recessed effects on buttons, input fields and wells:

/* Pressed button effect */

box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);

/* Inner glow */

box-shadow: inset 0 0 12px rgba(99, 102, 241, 0.3);

You can also combine inset and outset shadows on the same element. This is the foundation of neumorphism, where elements appear to be extruded from or pushed into the background surface.

Shadow Colors with rgba and hsla

Using semi-transparent colors for shadows is almost always better than solid colors. The alpha channel lets the background bleed through, creating a more natural result. On dark backgrounds, consider using slightly lighter shadow colors or colored shadows that match your accent:

/* Black shadow with opacity (most common) */

box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);

/* Colored shadow matching brand accent */

box-shadow: 0 4px 16px rgba(99, 102, 241, 0.25);

/* hsla for easier color adjustments */

box-shadow: 0 4px 16px hsla(239, 84%, 67%, 0.3);

Creative Effects

Box-shadow is not limited to basic elevation. With creative use of colors, spread and layering, you can build eye-catching effects:

Neon Glow

box-shadow:

0 0 8px rgba(99, 102, 241, 0.6),

0 0 24px rgba(99, 102, 241, 0.4),

0 0 64px rgba(99, 102, 241, 0.2);

Stacking multiple zero-offset shadows with increasing blur and decreasing opacity creates a neon glow. Change the color to green for a terminal look or pink for a retro vibe.

Neumorphism

background: #e0e0e0;

box-shadow:

8px 8px 16px rgba(0, 0, 0, 0.15),

-8px -8px 16px rgba(255, 255, 255, 0.8);

Neumorphism uses a light shadow and a dark shadow on opposite corners to create a soft, extruded look. The background color must match the parent for the effect to work properly.

Paper / Card Depth

box-shadow:

0 1px 1px rgba(0, 0, 0, 0.04),

0 2px 4px rgba(0, 0, 0, 0.04),

0 4px 8px rgba(0, 0, 0, 0.06),

0 8px 16px rgba(0, 0, 0, 0.08);

Four progressively larger layers create a rich, paper-like depth. This technique is popular for cards, popovers and floating panels in modern design systems.

Floating Effect

box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);

transform: translateY(-4px);

transition: all 0.3s ease;

Combining a large shadow with a negative translateY on hover makes an element feel like it is lifting off the page. This is a popular interaction pattern for clickable cards.

Performance Considerations

Box shadows are rendered on the CPU, not the GPU. Animating box-shadow directly (for example, transitioning from a small shadow to a large one on hover) triggers expensive repaints on every frame. Here are some tips to keep shadows performant:

  • Use a pseudo-element trick. Place the larger shadow on a ::after pseudo-element and animate its opacity instead of the shadow itself. Opacity changes are GPU-accelerated.
  • Avoid excessive blur values. A blur-radius of 100px or more is expensive to render, especially on large elements. Keep blur values reasonable.
  • Limit shadow count on lists. If you render hundreds of cards with multi-layered shadows, consider simplifying to a single shadow or applying shadows only on hover.
  • Use will-change sparingly. Adding will-change: box-shadow can promote the element to its own layer, but overusing it wastes memory. Only apply it to elements that actually animate.

box-shadow vs filter: drop-shadow()

CSS offers two ways to add shadows: box-shadow and filter: drop-shadow(). They look similar but behave differently:

  • box-shadow applies to the element's rectangular box, including border-radius. It supports spread-radius, inset shadows and multiple values.
  • filter: drop-shadow() applies to the element's visible shape, including transparent areas of images and SVGs. It does not support spread-radius or inset.
  • When to use drop-shadow. If you need a shadow that follows the actual outline of a PNG with transparency or an SVG icon, use drop-shadow. For everything else, box-shadow gives you more control.
  • Syntax difference. drop-shadow uses parentheses and does not accept spread-radius: filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2)).

Browser Support

The box-shadow property is supported in all modern browsers including Chrome, Firefox, Safari, Edge and mobile browsers. It has been stable since IE9, so there is no need for vendor prefixes in 2026. The filter: drop-shadow() function also has universal support across modern browsers.

Build box shadows visually

Adjust offsets, blur, spread and color with a visual editor. Preview your shadow in real time and copy the CSS code instantly.

Open CSS Box Shadow Generator