Vanilla Breeze

Shadows

How depth works in Vanilla Breeze: a themeable elevation ramp, the box-shadow vs drop-shadow distinction that trips most authors up, and the opt-in data-shadow effects (tint, material, shape, glow).

Depth in Vanilla Breeze is a token layer, not a component — shadows have no runtime behaviour to encapsulate, so they ship as CSS custom properties and a small attribute API. This page covers the one distinction authors get wrong (box-shadow vs drop-shadow), the elevation ramp, and the opt-in data-shadow effects.

box-shadow vs drop-shadow

This is the single most useful thing to know about shadows. They look similar but paint completely differently, and reaching for the wrong one is why a shadow on a rounded badge or a transparent logo comes out as an unexpected rectangle.

box-shadowfilter: drop-shadow()
PaintsThe border-box — always a rectangle (rounded by border-radius).The element’s actual alpha — follows the real shape.
Use forCards, panels, popovers, raised surfaces.clip-path shapes, transparent PNGs, SVG, text.
Composes withOther box-shadows (comma-stacked layers).Other filter functions.
VB hook--shadow-* tokens, data-shadow="tint", data-shadow="material"data-shadow="shape"

A transparent PNG, SVG, or text element carries its own alpha, so drop-shadow goes directly on it. Only clip-path needs the wrapper, because the clip would otherwise cut the shadow it just generated.

The elevation ramp

Six themeable levels live in src/tokens/shadows.css. The default theme uses layered, “photographic” ramps at the higher steps — a tight contact stop plus progressively softer ambient stops — so raised surfaces read with real depth instead of one flat blur.

Reference the tokens directly — box-shadow: var(--shadow-m).

TokenUse
--shadow-xs … --shadow-2xlThe elevation scale, lowest to highest.
--shadow-innerInset shadow for wells and pressed states.
--shadow-flushHairline + soft drop, an alternative to border: 1px solid on raised surfaces. See Feel.
--shadow-noneExplicit no-shadow reset.

The data-shadow effects

Opt-in, composable, theme-aware effects — the depth-layer sibling of data-border-effect. They read VB tokens, so they re-skin with the active theme, and they live in @layer bundle-effects so they win over a component’s own box-shadow. No JavaScript, no custom element.

TokenEffect
tintLuminous, accent-tinted drop shadow derived from --color-accent. Re-tints with the theme.
materialRests at --shadow-m, raises to --shadow-xl with a translateY(-4px) lift on hover/focus.
shapeAlpha-true drop-shadow for transparent PNG, SVG, or text — not the border-box rectangle. For a clip-path shape, put it on a wrapper (a clipped element clips its own shadow).
glowSoft accent halo. Static by default; add flicker for a gentle pulse.

Reduced motion

Motion is gated. material keeps its elevation feedback under prefers-reduced-motion: reduce but drops the lift transform and transition. glow is static by default; its flicker pulse only runs under prefers-reduced-motion: no-preference, so the static halo is the reduced-motion fallback.

On busy backgrounds

tint and glow keep their color-mix transparency at or above ~50% so the hue survives over textured surfaces; pushed more opaque, the colour muddies.

Live demo

The elevation ramp followed by all four effects (move the pointer over the material card to see it raise):

Why no shadow-wc

Surface (bg-wc) and edge (border-wc) earn web components — SVG/canvas overlays, perimeter geometry, resize refitting. Depth needs none of that: box-shadow and drop-shadow paint with the box and scale with it automatically. A component would wrap nothing, so depth ships as tokens and this attribute layer instead.

↑