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-md). Numeric aliases --shadow-1--shadow-6 map onto the same scale for Open Props compatibility. Themes override these tokens, so each pack carries its own shadow language (brutalist hard offsets, claymorphism’s inset highlights, and so on) without any component changes.

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-md, 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.