🎨 CSS

CSS Box Shadow Generator

Stack up to 4 layered shadows, customize offsets, blur, and spread, or choose curated UI presets with clean CSS and Tailwind output.

Preview
Trending Design Presets
Shadow Layers
Generated Declaration

Understanding Horizontal and Vertical Offsets in CSS Shadows

Quick Answer: The CSS Box Shadow Generator is a free visual UI design tool that generates single and multi-layered CSS box-shadow effects. It supports up to 4 stacked shadow layers with independent X/Y offsets, blur radii, spread distances, opacity controls, and inset toggles, plus one-click export for CSS, Tailwind CSS (shadow-[...]), and CSS Variables.

The first two numerical parameters of the CSS box-shadow property define directional vectors in two-dimensional space. Horizontal offset (X) projects the shadow along the X-axis: positive values shift the shadow to the right, while negative values shift it to the left. Vertical offset (Y) projects the shadow along the Y-axis: positive values shift the shadow downward toward the bottom of the viewport, while negative values shift it upward.

In modern interface engineering, natural lighting models almost universally assume an overhead light source (simulating natural sunlight or ceiling fixtures). Consequently, realistic UI elevation systems (such as those pioneered by Google Material Design and Apple Human Interface Guidelines) typically lock the horizontal offset at 0px while scaling the vertical offset upwards as an element gains z-axis elevation.

The Geometric Mechanics of Blur Radius vs Spread Radius

A frequent point of confusion among frontend developers is the difference between blur radius and spread radius. While both properties make the shadow footprint appear larger on the page, they operate via fundamentally distinct mathematical algorithms:

Creating Inset Shadows for Tactile, Debossed States

Prefacing a box shadow declaration with the inset keyword completely flips the rendering pipeline. Instead of casting a shadow outward onto the surrounding document canvas, the browser clips the shadow strictly to the interior perimeter of the element box.

Inset shadows simulate debossed cavities, carved recesses, and sunken button wells. In interactive design, toggling from an elevated outer shadow on hover to a tight inset shadow on click (:active) creates an authentic physical clicking sensation, providing immediate tactile confirmation to the user.

Box Shadow Properties and Rendering Parameter Matrix

CSS Parameter Type & Units Visual Effect Produced Paint Performance Cost Design Best Practice
offset-x (Horizontal) Length (e.g., 0px, 10px) Shifts shadow left or right Low (Offset rasterization) Keep 0px for centered ambient drop
offset-y (Vertical) Length (e.g., 4px, 20px) Shifts shadow downward (elevation) Low (Offset rasterization) Increase with elevation (e.g. cards)
blur-radius Length (≥ 0px) Feathers shadow edges into gradient High (Gaussian convolution) Layer a tight blur with a wide ambient blur
spread-radius Length (Negative to Positive) Expands or shrinks shadow base shape Moderate (Shape recalculation) Use negative values to prevent messy bleed
inset Keyword Optional keyword prefix Casts shadow inward into the box Moderate (Inner clip masking) Standard for pressed states and sunken wells
Multi-layer Stack Comma-separated layer list Photorealistic 3D light elevation Linear with layer count (Cap at 3-4) Order sharpest layer 1st, softest last

Why Layer Ordering Matters in Multi-Shadow Stacks

Real-world shadows are never homogeneous. When an object rests above a table under ambient light, it generates a tight, dark contact shadow directly beneath its base where light is completely occluded, surrounded by a soft, highly diffused ambient shadow where scattered light partially penetrates.

To recreate this photorealistic depth in CSS, developers stack multiple comma-separated shadow layers. When interpreting comma-separated shadows, the CSS specification dictates that the first declared shadow renders in the foreground closest to the viewer, while each subsequent shadow renders progressively behind it. To achieve maximum depth fidelity, declare your layers in descending sharpness:

  1. Layer 1 (Contact Occlusion): Tight vertical offset (e.g., 2px), small blur (e.g., 4px), higher opacity (e.g., 15%). Grounds the element directly to the surface.
  2. Layer 2 (Direct Penumbra): Moderate offset (e.g., 8px), medium blur (e.g., 16px), moderate opacity (e.g., 8%). Represents primary directional shadow.
  3. Layer 3 (Ambient Dispersion): Large offset (e.g., 24px), expansive blur (e.g., 48px), low opacity (e.g., 4%), negative spread (e.g., -12px). Simulates atmospheric light scatter.

Alpha Transparency and Hex-to-RGBA Conversion

A classic visual blunder in web styling is using solid hex colors (such as #333333) for drop shadows. Solid shadows create unnatural muddy blotches that obscure underlying wallpaper patterns and photographic backgrounds.

Utility369 CSS Box Shadow Generator automatically decomposes selected color inputs into red, green, and blue channels, formatting the output into an explicit rgba(r, g, b, a) color declaration. By controlling alpha transparency independently for each layer, shadows blend harmoniously across light mode, dark mode, and multi-color gradient backdrops.

Performance Optimization: Animating Shadows Without Frame Drops

While CSS box-shadow is universally supported across all modern browsers, it is one of the most computationally expensive properties for a rendering engine to repaint. When an element animates its box-shadow during hover transitions or scroll events, the browser must re-run its Gaussian blur rasterization shader across thousands of pixels on every single animation frame, frequently triggering GPU frame drops on mobile devices.

To achieve buttery 60fps or 120fps elevation transitions on hover, frontend architects utilize the Pseudo-Element Opacity Technique:

/* Performant Hover Shadow Pattern */
.card {
  position: relative;
  border-radius: 16px;
  background: #ffffff;
  /* Resting subtle shadow */
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 16px;
  /* Pre-rendered elevated shadow */
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.card:hover {
  transform: translateY(-4px);
}

.card:hover::after {
  opacity: 1; /* Hardware-accelerated GPU opacity fade */
}

Accessibility Compliance and Keyboard Focus Rings

While multi-layer box shadows enhance spatial hierarchy, they must never replace functional accessibility indicators. Under WCAG 2.1 Success Criterion 2.4.7 (Focus Visible), keyboard navigators must be able to visually track the currently focused control at all times.

Relying on subtle drop shadows to convey keyboard focus violates contrast standards because shadow gradients fail the required 3:1 contrast ratio against surrounding backgrounds. Always supplement decorative box shadows with a distinct, high-contrast :focus-visible outline or a saturated multi-pixel focus ring.

Frequently Asked Questions

How do I generate a CSS box shadow?

Use our visual generator to adjust the sliders for the X and Y offsets, blur radius, and spread. Once you are happy with the visual preview, copy the generated CSS code into your stylesheet.

What is an inset box shadow?

Adding the inset keyword to the box-shadow property changes the drop shadow from an outer shadow into an inner shadow, making the element look like it is sunken into the page.

What is the actual difference between blur and spread?

Spread grows or shrinks the underlying shadow shape by a fixed distance with hard edges. Blur softens whatever edges that shape has into a gradient without changing its base size.

Which shadow layer appears on top when I stack multiple layers?

The first declared shadow layer renders closest to the viewer in front of subsequent layers. For realistic depth, place your sharpest, darkest ambient contact shadow first, followed by softer ambient diffusion layers.

Why does the generated CSS use rgba() instead of a hex color?

Using rgba() allows explicit control over shadow alpha transparency. Translucent shadows blend realistically over varied background textures, whereas opaque hex colors create harsh and artificial silhouettes.

What does the Inset checkbox do?

It flips the shadow from casting outward to casting inward within the element box boundary. This is the standard technique for pressed buttons, sunken form fields, and tactile debossed UI elements.

Why is this tool limited to four shadow layers?

While CSS supports unlimited comma-separated shadow layers, three or four layers fully achieve hyper-realistic elevation and smooth penumbras without incurring excessive GPU fragment shader re-rasterization costs.

Can I use a negative spread value?

Yes. A negative spread radius shrinks the shadow perimeter smaller than the element bounding box, enabling tight, subtle shadows that do not bleed past the horizontal edges of floating cards.

How does box-shadow interact with element border-radius?

Per the CSS specification, box-shadow automatically conforms to the curved corners defined by border-radius, projecting identical rounded contours on both outer and inset shadow passes.

Does animating box-shadow cause performance lag on mobile browsers?

Yes. Box shadow blur animations force CPU or GPU re-rasterization on every frame. For optimal 60fps performance, animate an opacity transition on a pseudo-element containing a pre-rendered shadow rather than animating box-shadow directly.