Understanding the five box-shadow values
The box-shadow property takes its values in a fixed order, and knowing what each one does turns guesswork into intent:
Horizontal offset moves the shadow right (positive) or left (negative). Vertical offset moves it down or up. Blur radius controls how soft the edge is — 0 gives a hard-edged shape, higher values diffuse it. Spread grows or shrinks the shadow before blurring, which is the value most people forget exists. Colour finishes it, and is almost always best expressed with alpha transparency.
Add inset at the start and the shadow is drawn inside the element instead of outside — the standard way to make a field look recessed or a button look pressed.
Why realistic shadows use low opacity and large blur
The single biggest giveaway of an amateur shadow is opacity that is too high. Real shadows in the physical world are diffuse and subtle; a shadow at 50% black looks like a sticker, not depth. Professional interfaces overwhelmingly use something in the range of 8–25% opacity with a generous blur.
The second giveaway is a shadow with no vertical offset. Light in almost every interface is implicitly from above, so shadows should sit slightly below their element. A shadow offset only horizontally reads as wrong even to people who cannot articulate why.
Layering shadows for real depth
The technique that separates polished UI from flat UI is stacking multiple shadows in a single declaration, separated by commas. Physical objects cast both a tight, darker contact shadow right at their base and a wider, softer ambient shadow further out. Simulating both is far more convincing than one shadow trying to do everything:
box-shadow: 0 1px 2px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.12);
Build an elevation scale from this idea — a small shadow for resting cards, a medium one for hover, a large one for modals — and apply it consistently. Consistent elevation is what makes an interface feel like a coherent system rather than a collection of screens.
Shadows, performance and dark mode
Box shadows are cheap to paint but not free, and animating them can cause repaints on every frame. If you want a lift-on-hover effect, transition transform for the movement and keep the shadow change modest — or pre-render two shadow states and cross-fade a pseudo-element, which stays on the compositor.
Dark interfaces need a different approach entirely. A black shadow on a dark background is nearly invisible, so depth has to come from elsewhere: a subtle light border on the top edge, a slightly lighter surface colour, or a coloured glow that matches your accent. That is why this site uses rim highlights and soft coloured glows rather than heavy drop shadows.