Dimensions

Animate width and height of elements.

Animate the width and height of elements — from pixel values to percentages, viewport units, and auto. Ideal for accordions, progress bars, and responsive resize effects.

Basic Usage

Pass width and/or height inside from or to. Numbers are treated as pixels; strings accept any CSS unit.

typescript
import { Motion } from "@motion.page/sdk";

Motion("expand", ".box", {
  from: { width: 0, height: 0 },
  to: { width: 200, height: 200 },
  duration: 0.5,
  ease: "power2.out",
}).play();

Because the SDK auto-resolves the missing endpoint from the element’s computed CSS, you only need to specify the side that differs from the element’s natural state:

typescript
// Start at zero height, expand to whatever height the element naturally has
Motion("reveal", ".card", {
  from: { height: 0 },
  duration: 0.4,
  ease: "power2.out",
}).onPageLoad();

Properties

PropertyTypeDescription
widthnumber | stringTarget width. Numbers are px. Strings for units: '100%', 'auto', '50vw', '12rem'
heightnumber | stringTarget height. Numbers are px. Strings for units: '100%', 'auto', '50vh', '12rem'

String Values & Units

Pass a CSS string whenever you need units other than px:

typescript
Motion("expand", ".box", {
  to: { width: "100%", height: "50vh" },
  duration: 0.6,
  ease: "power2.out",
}).play();

Valid string values: '200px', '100%', '50vw', '50vh', '4rem', 'auto'.

Height auto — Accordion Pattern

Animating to height: 'auto' expands an element to its natural content height — the exact pattern for accordions and collapsible sections. The SDK calculates the target height at runtime, so the animation adapts to any content length.

typescript
Motion("accordion", ".content", {
  from: { height: 0 },
  to: { height: "auto" },
  duration: 0.4,
  ease: "power2.out",
}).play();

Add .onClick() with each: true to make every panel toggle independently:

typescript
Motion("accordion", ".panel", {
  from: { height: 0 },
  to: { height: "auto" },
  duration: 0.4,
  ease: "power2.out",
}).onClick({ each: true });

CSS required: Add overflow: hidden to .panel so content is clipped cleanly during the animation.

Progress Bar

Animate width from '0%' to a target percentage for clean loading or progress indicators:

typescript
Motion("progress", ".bar", {
  from: { width: "0%" },
  to: { width: "75%" },
  duration: 1.2,
  ease: "power2.out",
}).play();

Responsive Resize on Scroll

Shrink a hero image as the user scrolls, letting surrounding content adapt to the new layout:

typescript
Motion("resize", ".hero-image", {
  from: { width: "100%", height: "100vh" },
  to: { width: "60%", height: "50vh" },
  duration: 1,
}).onScroll({ scrub: true });

Performance

width and height animations cause layout reflows — the browser recalculates positions and sizes of surrounding elements on every frame. This is more expensive than transform-based animations.

Prefer Scale when layout reflow isn’t needed. scale, scaleX, and scaleY run on the GPU compositor and don’t affect surrounding elements — they’re significantly faster for simple zoom or pop effects.

Use dimension animations when you need reflow, for example:

  • Accordions where surrounding content must shift to accommodate the expanded panel
  • Progress bars that push adjacent content
  • Responsive resize where neighboring elements must reposition

Additional tips:

  • Add overflow: hidden on containers to prevent content from spilling during the transition
  • Avoid animating width and height simultaneously on many elements — batch them or use a single container element
  • Combine with will-change: height (sparingly) on elements that animate frequently to hint GPU promotion ahead of time