Skip to content
Sign in
FramesDevice tiltMenu

Device tiltPro

A CSS 3D perspective wrapper that settles a frame flat as it scrolls into view. Flat under reduced motion.

ProScroll inside the panel: the laptop and phone settle flat as they reach the middle, on the compositor.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/device-tilt

Usage

tsx
import { DeviceTilt } from "@/components/ui/chatcn/pro/device-tilt"

<DeviceTilt from={{ x: 28 }}>
  <LaptopFrame width={720}>{app}</LaptopFrame>
</DeviceTilt>

Scroll mode runs on a scroll timeline where the browser has one, so the compositor moves the frame and touch scrolling never waits on JavaScript. Elsewhere a passive, frame throttled listener does the same. Browsers raster a tilted layer at a lower resolution, so very small text softens while the frame is turned and sharpens as it settles: design the screen to read at its resting angle.

A screen scaled far below 1x shrinks its controls under the 24 px minimum target. When a frame is a picture (a hero, a gallery card), pass inert to the frame: the content stays visible but leaves the tab order and the accessibility tree. Leave it off and the screen stays fully live.

Examples

Your own progress

ProDrive the tilt with a value from 0 to 1, here from a range input.

Props

PropTypeNotes
mode"scroll" | "static"Default scroll
from{ x?, y?, z? }Start angle in degrees, and the static angle. Default x 24
to{ x?, y?, z? }Resting angle. Default flat
progressnumber0 to 1. Overrides scroll
perspectivenumberIn px. Default 1600

Keyboard

No keyboard behavior. Nothing triggered by the keyboard animates.

Accessibility

  • The tilt is decoration; the content inside stays interactive and is read normally unless you mark the frame inert.
  • A scrolling panel around a tilt (as in the demo) takes focus, so it scrolls from the keyboard too.

Motion

  • Scroll mode settles flat by the time the frame is centered in the viewport.
  • Under reduced motion every mode renders flat.