On this page
A shadow is useful when it explains which surface sits above another. It becomes noise when every card floats at a different height or when a dark halo competes with the content.
Build shadows as a small system of elevation cues. This approach combines layered CSS, deliberate borders, and repeatable checks rather than adjusting each component until it looks vaguely softer.
Decide what elevation means
Define surface relationships first. A static settings section might need only a border, while a menu must clearly separate from the content underneath. A modal has a different relationship again, often requiring a backdrop as well as a shadow.
Use the Multi-Layer Box Shadow Generator below to compare a tight contact layer with a broad ambient layer. Keep the preview background close to the real application surface so the result does not depend on an unrealistic white canvas.
Choose three elevation levels before creating dozens of variants: resting cards, floating controls, and overlays. Each level should correspond to behavior or hierarchy, not merely a component's importance in a presentation.
Agree on a consistent light direction. A slight downward offset usually reads naturally in interface layouts, but consistency matters more than imitating a physical room. Mixing strongly directional shadows with centered glows makes the system feel incoherent.
Understand the shadow components
A shadow contains horizontal offset, vertical offset, blur radius, optional spread, and color. MDN's box-shadow reference documents the order and how multiple comma-separated layers combine.
The contact layer should suggest closeness to the surface. Keep it relatively tight and restrained. The ambient layer spreads more broadly and usually needs lower opacity so it does not become a visible gray cloud.
:root {
--shadow-raised:
0 1px 2px rgb(15 23 42 / 10%),
0 8px 24px -8px rgb(15 23 42 / 18%);
--shadow-overlay:
0 2px 6px rgb(15 23 42 / 12%),
0 20px 48px -12px rgb(15 23 42 / 24%);
}
.card {
background: #ffffff;
border: 1px solid #dbe2ea;
border-radius: 1rem;
box-shadow: var(--shadow-raised);
}
.menu { box-shadow: var(--shadow-overlay); }The negative spread in the broad layer keeps the shadow from extending equally strongly around every edge. It is a design choice, not a performance optimization. Adjust it while inspecting corners and nearby elements.
Avoid adding layers merely because a generator supports them. Two carefully chosen layers often provide enough depth. Extra layers increase maintenance and can alter the color where shadows overlap without producing a meaningful improvement.
Balance borders, backgrounds, and depth
A shadow cannot solve every separation problem. On a pale canvas, a white card may need a fine border. On a dark canvas, a slightly lighter surface can provide clearer separation than an enormous black blur.
Use surface contrast as the first cue and shadow as reinforcement. A menu should remain understandable if the shadow disappears in a high-contrast environment or is difficult to perceive on a low-quality display.
Do not substitute shadow for a keyboard focus indicator. The WAI keyboard guidance explains why visible focus matters. A decorative halo that appears on every card does not identify the currently focused control.
For more complex translucent surfaces, compare glassmorphism card techniques. Glass and shadow can work together, but combining heavy blur, strong borders, and large shadows often overstates depth.
Keep content hierarchy independent of elevation. A section heading should not need a dramatic floating container to be recognizable. Typography, spacing, and grouping frequently provide a cleaner solution with less visual weight.
Inspect adjacent components together. Two individually attractive shadows may merge into one dark band when cards sit close together. Increase spacing, reduce the ambient layer, or replace the repeated shadow with a shared container boundary.
Handle interaction without expensive spectacle
A hover treatment should confirm interactivity rather than make the page feel unstable. A subtle translation or surface change is usually enough. Keep motion distance small and avoid moving surrounding content during the transition.
Animating a large blur or repeatedly changing a shadow can trigger painting work. The web.dev rendering guidance explains the rendering pipeline and why the affected property matters. Measure actual behavior instead of assuming every short transition is cheap.
.interactive-card {
transition: transform 160ms ease;
}
.interactive-card:hover {
transform: translateY(-2px);
}
.interactive-card:focus-visible {
outline: 3px solid #4338ca;
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
.interactive-card { transition: none; }
.interactive-card:hover { transform: none; }
}Use real interactive elements for clickable cards, and avoid wrapping unrelated controls in a single giant link. The shadow can imply clickability, but the semantic structure must deliver the expected keyboard behavior.
Test touch layouts without relying on hover. A raised card should not hide essential information until a pointer enters it. If the interaction requires a state change, expose that state through an explicit control and a persistent visual cue.
Tune and document the system
Review every elevation token on light, tinted, and dark surfaces. The same values rarely work equally well everywhere. In dark mode, combine surface lightness and a subtle border rather than simply increasing black shadow opacity.
Return to the shadow generator to compare small adjustments side by side. Change one parameter at a time and use representative spacing. A preview with huge empty margins can conceal how much a shadow interferes with neighboring components.
Use the contrast checker for text, borders where required, and focus-related color pairs. A pleasant shadow does not compensate for a weak label or an invisible input boundary.
Create a review fixture with a card grid, an open dropdown, a dialog, and a focused action. Capture the same states after token changes. This helps distinguish an intentional system update from a local tweak that accidentally affects every overlay.
Document where each token belongs and when no shadow is preferred. Include notes about clipping containers, because an ancestor with hidden overflow may cut off the effect. Fix the layout boundary instead of making the shadow larger in an attempt to overcome clipping.
Key takeaways
- Define elevation roles before styling individual components.
- Combine a tight contact layer with a restrained ambient layer.
- Use borders and surface colors when shadows cannot provide reliable separation.
- Preserve an independent, visible keyboard focus indicator.
- Profile motion and avoid unnecessary blur animation.
- Maintain shared tokens and review them in complete interface states.
Reach designers & developers at work
Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.
Become a sponsor