Scale
Scale elements uniformly or independently on X/Y axes.
Scale controls how large or small an element appears during an animation. Use scale for uniform scaling, or scaleX / scaleY for independent axis control. All three are unitless — 1 means normal size.
Basic Scale
Pass scale inside from or to. A value of 1 is the element’s natural size.
import { Motion } from "@motion.page/sdk";
Motion("grow", ".box", {
from: { scale: 0 },
duration: 0.5,
ease: "back.out(1.7)",
}).onPageLoad(); Because scale: 1 is a natural CSS default, omitting to is correct here — the SDK resolves the missing endpoint from the element’s current computed style and animates to full size automatically.
Common Values
| Value | Result |
|---|---|
0 | Invisible (zero size) |
0.5 | Half size |
1 | Normal size (natural default) |
1.5 | 150% size |
2 | Double size |
Independent Axes — scaleX and scaleY
Use scaleX and scaleY when you want non-uniform scaling — stretching or squashing on one axis only.
// Squash horizontally
Motion("squash", ".box", {
to: { scaleX: 0.6, scaleY: 1.2 },
duration: 0.3,
ease: "power2.inOut",
}).onHover({ each: true, onLeave: "reverse" }); Common Patterns
Zoom In on Scroll
Reveal an element by scaling it in as it enters the viewport.
Motion("zoom-in", ".card", {
from: { scale: 0.8, opacity: 0 },
duration: 0.6,
ease: "power2.out",
}).onScroll({ scrub: false, toggleActions: "play none none none" }); Pop In with Opacity
Combine scale and opacity for a soft, polished entrance effect.
Motion("pop-in", ".modal", {
from: { scale: 0.9, opacity: 0 },
duration: 0.4,
ease: "back.out(1.4)",
}).onPageLoad(); The two properties animate in parallel — the element fades in while simultaneously growing to its natural size.
Pulse (Infinite Repeat with Yoyo)
Gently pulse an element to draw attention.
Motion("pulse", ".badge", {
to: { scale: 1.15 },
duration: 0.6,
ease: "power1.inOut",
repeat: { times: -1, yoyo: true },
}).onPageLoad(); yoyo: true reverses the animation on each cycle, producing a continuous breathe effect without any visible jump.
Rubber Band (scaleX + scaleY)
Animate scaleX and scaleY in opposite directions for a rubbery, organic feel.
import { Motion } from "@motion.page/sdk";
Motion("rubber-band", ".button", [
{
target: ".button",
to: { scaleX: 1.3, scaleY: 0.7 },
duration: 0.15,
ease: "power2.out",
},
{
target: ".button",
to: { scaleX: 0.85, scaleY: 1.15 },
duration: 0.1,
ease: "power2.inOut",
},
{
target: ".button",
to: { scaleX: 1.05, scaleY: 0.95 },
duration: 0.1,
ease: "power2.inOut",
},
{
target: ".button",
duration: 0.15,
ease: "power2.out",
},
]).onClick({ each: true }); Transform Origin
Scale always happens around the transform origin — by default the element’s center (50% 50%). Change this with transformOrigin to scale from a corner, edge, or any custom point.
// Scale up from the bottom-left corner
Motion("corner-scale", ".card", {
from: { scale: 0, transformOrigin: "0% 100%" },
duration: 0.5,
ease: "power3.out",
}).onPageLoad(); See the Transform Origin page for all supported values and examples.