3D✨ Premium

Shadow Perspective

A 150 × 100 px indigo card sitting above its ground shadow, a blurred ellipse squashed flat; on hover, tap or keyboard focus, the card rises 10 px while the shadow stays on the ground, fades by half and spreads (blur 10 to 15 px): the cue of an object lifted off a table, nothing else moves. CSS only, no JavaScript.

CSS3DShadow

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →

3 usage examples

The refurbished phone lifts off the table — a repair shop's product page — Shadow Perspective example 1

① The refurbished phone lifts off the table — a repair shop's product page

WhenA smartphone drawn flat, dark screen ("Tested", "Grade A", "battery 92%"), sitting above its shadow on the workbench; it lifts as when you pick it up, next to the description and the price.
WhyOnly the shadow staying on the ground and spreading says "real object set there"; a 3D tilt like Perspective Tilt (fx-0003) would read as a card, not an object.
SettingsRoot without background over a light workbench backdrop; object enlarged into a 118 × 224 px phone (22 px corners, 4 px frame); stronger brown shadow (rgba(40, 30, 20, .6)); the scene lifts the phone in a loop and yields to the mouse.
The honey jar you take off the shelf — a beekeeper's online shop — Shadow Perspective example 2

② The honey jar you take off the shelf — a beekeeper's online shop

WhenThree jars (chestnut, acacia, wildflower) side by side on a wooden shelf; the hovered one lifts and shows its price above the lid.
WhyThe lift with a shadow staying on the board echoes the gesture of taking a product off the shelf, with no zoom and no selection frame.
SettingsOne copy of the effect per jar; 96 × 112 px jars in honey colors, lid drawn by ::before (free in the sold code), cream label; amber shadow rgba(90, 55, 10, .55); price shown with the lift. The scene lifts the jars one after the other.
The stoneware bowl lifting off the table — a potter's shop — Shadow Perspective example 3

③ The stoneware bowl lifting off the table — a potter's shop

WhenA bowl seen from the front, "Brittany night" blue glaze, on a light table next to its description and price; it lifts and the shadow spreads.
WhyOn a light table, the soft shadow widening is enough to give weight and volume to a ceramic piece, without a photo.
SettingsObject redrawn as a 200 × 96 px bowl (bottom corners rounded at 100 px, rim as ::before); shadow narrowed to 70% of the width, brown rgba(50, 40, 30, .5); cream background.

How it works

The root .fx-0020-root (#0a0a0f background, at least 300 px tall) centers a 280 × 200 px .demo-3d frame, then .shadow-perspective-container, whose 40 px padding leaves room for the lift and the shadow. The object is .shadow-perspective: 150 × 100 px, #6366f1 → #8b5cf6 gradient, 0.75 rem corners, bold centered text, tabindex="0", a 0.3 s transition on its transform.

The shadow is its ::after pseudo-element: a black ellipse at 30% (rgba(0, 0, 0, .3), border-radius: 50%), 80% of the card's width, 20 px tall, set 20 px below it, blurred at 10 px and laid down by rotateX(80deg) — with no perspective above, that rotation amounts to squashing it to 17% of its height (cos 80°), about 3.5 px before the blur: a flat contact shadow. On hover (or :focus-visible), the card takes translateY(-10px) and the shadow moves to bottom: -30px, 50% opacity and a 15 px blur, in 0.3 s. The card rises 10 px and the shadow's anchor moves 10 px further below it: on screen, the shadow does not move, it stays on the ground, lightens and widens. Measured: 2.4% of pixels change on hover, identically in Chromium 151, Firefox 153 and WebKit 26.5.

The shadow is black at 30%: on the original dark background it barely shows, and the card's lift carries the effect. It really reads on a light or mid-tone background — a table, a shelf, a product page — as in the scenes above. The blur works on an already squashed ellipse: it gives a soft edge without thickening the shadow, which a growing box-shadow cannot do (it surrounds the whole card, not just its underside).

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, a block scoped to .fx-0020-root removes the transitions and the lift: the card stays put, the shadow lightens and spreads at once, and a 3 px violet outline (rgba(167, 139, 250, .6)) marks hover and focus, which makes it visible even on the dark background. Measured in Chromium and Firefox: transform unchanged, outline present on hover.
  • Keyboard: the card has tabindex="0" and focus gives the same lift as hover, plus a 2 px #c4b5fd outline (10.7:1 on the background). If the card leads to a page, replace the div with a link <a class="shadow-perspective" href="…">: nothing else changes.
  • Contrast: bold white text at 4.47:1 on the indigo #6366f1 and 4.2:1 on the violet #8b5cf6, under the 4.5:1 threshold for 16 px text: darken the gradient if the card carries text that matters.
  • Touch: with a finger, the tapped card lifts (measured with Chromium touch emulation and in Firefox) and stays up until the next tap.

Browser compatibility

CSS only (transform, filter: blur() on a pseudo-element, :focus-visible), no dependencies. Measured in Chromium 151, Firefox 153 and WebKit 26.5: same render at rest and on hover (under 0.2% apart), same reduced motion, 0 errors. No stacked 3D planes: the shadow's rotation is a plain squash, rendered identically by WebKit.

Chrome 86+✓ Full
Firefox 85+✓ Full
Safari 15.4+✓ Full (render measured in WebKit 26; not checked on a real Safari)
Edge 86+✓ Full
Mobile iOS✓ Hover on tap not checked on a real iPhone
Android Chrome✓ Full

Without filter, the shadow becomes a sharp, dark 3.5 px ellipse: the effect still reads, only harder. Without :focus-visible, keyboard focus only gets the browser's ring.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0020-root">
  <div class="demo-3d">
    <div class="shadow-perspective-container">   <!-- 40 px padding for the lift and the shadow -->
      <div class="shadow-perspective" tabindex="0">Hover Me</div>   <!-- ::after = ground shadow -->
    </div>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Lift height (CSS — hover translateY(-10px)) 10 px To keep the shadow on the ground, move its anchor down by the same amount: a 16 px lift, bottom: -36px on hover.
Resting shadow (CSS — ::after: color, bottom, width, filter) rgba(0, 0, 0, .3); 20 px below the object; 80%; 10 px blur On a light background, a warm tint (brown at 40-60%) looks more natural than black. The width follows the object's base: 70% for a bowl, 80% for a card.
Lifted shadow (CSS — hover ::after: bottom, opacity, filter) 30 px; 0.5; 15 px blur The higher the object, the paler and wider the shadow should get: with a 20 px lift, try 0.35 and a 20 px blur.
Shadow squash (CSS — rotateX(80deg)) 80° 70° gives a thicker shadow (a table seen from higher up); 85° an almost flat line.
Object (CSS — size, background, corners of .shadow-perspective) 150 × 100 px, #6366f1 → #8b5cf6, 0.75 rem The effect works on any shape: the scenes turn it into a phone, a jar and a bowl. The ::before pseudo-element stays free for a detail (lid, rim).
Duration (CSS — card and shadow transition) 0.3 s Keep the same duration on both, or the shadow arrives before or after the object.

FAQ

It is black at 30%: on #0a0a0f it almost blends into the background, and what you mostly see is the card rising. The effect is made for a light or mid-tone background, where a contact shadow reads as in real life: a table, a shelf, a product page. The three scenes show it on cream and wood backgrounds.
A box-shadow surrounds the whole card: it says "card floating above the page". Here the shadow is a flat ellipse set under the object, apart from it: when the object rises, it stays on the ground, fades and spreads, which says "object lifted off a surface". It is the cue product photos give.
Yes: put your image inside .shadow-perspective (or set it as its background), adjust its size, and match the shadow's width to the object's base. A cut-out image (transparent background) works best: the shadow then shows right under the object.