Beta Status
This library is still in early beta and the API is subject to change and may get daily breaking changes. The documentaton may not be up to date with the latest features and include missing or outdated information. You can always create an issue on GitHub or even better a pull request to fix the documentation or add new features.
Motion Component
The motion proxy exposes a component for every HTML and SVG element. Motion components accept all native props plus animation-specific props.
import { motion } from "motion-solid";
// HTML elements
<motion.div />
<motion.button />
<motion.section />
// SVG elements
<motion.svg />
<motion.path />
<motion.circle />
Basic Example
<motion.div
class="card"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, ease: "ease-out" }}
>
Fade in from below
</motion.div>
Animation Props
initial
The starting state. Can be an animation target, a variant label, or false to skip the initial animation.
// Animation target
<motion.div initial={{ opacity: 0, scale: 0.8 }} />
// Variant label
<motion.div initial="hidden" variants={variants} />
// Skip initial animation
<motion.div initial={false} animate={{ x: 100 }} />
animate
Target to animate to on mount and when props change. Can be a target object, variant label, or array of labels.
// Animation target
<motion.div animate={{ opacity: 1, x: 50 }} />
// Variant label
<motion.div animate="visible" variants={variants} />
// Multiple variants (merged in order)
<motion.div animate={["visible", "highlight"]} variants={variants} />
// CSS custom properties
<motion.div animate={{ "--progress": 0.5, "--color": "#ff0000" }} />
exit
Target to animate to when the component leaves. Requires AnimatePresence.
<AnimatePresence>
<Show when={visible()}>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, y: -20 }}
/>
</Show>
</AnimatePresence>
transition
Controls how values animate. Can be set per-prop or as a default.
// Default for all values
<motion.div
animate={{ x: 100, opacity: 1 }}
transition={{ type: "spring", stiffness: 200 }}
/>
// Per-prop overrides
<motion.div
animate={{ x: 100, opacity: 1 }}
transition={{
x: { type: "spring" },
opacity: { duration: 0.2 },
}}
/>
// Using transitionEnd for final values
<motion.div
animate={{ opacity: 1 }}
transition={{ transitionEnd: { display: "none" } }}
/>
Transition types:
"spring"- Physics-based withstiffness,damping,mass"tween"- Duration-based withduration,ease"keyframes"- Step through an array of values"inertia"- Decelerate from initial velocity
variants
Map of named animation targets. See Variants.
const variants = {
hidden: { opacity: 0 },
visible: { opacity: 1 },
};
<motion.div variants={variants} initial="hidden" animate="visible" />;
custom
Data passed to variant functions. Also provided by AnimatePresence.
const variants = {
visible: (delay: number) => ({
opacity: 1,
transition: { delay },
}),
};
<motion.div variants={variants} custom={0.2} animate="visible" />;
inherit
Set to false to prevent inheriting variants from ancestors.
<motion.ul variants={list} animate="show">
<motion.li variants={item} /> {/* inherits "show" */}
<motion.li inherit={false} /> {/* does not inherit */}
</motion.ul>
Style
Regular Solid style object, merged with animated values. Use kebab-case for CSS and transform properties (scale-x, rotate-y, etc).
<motion.div style={{ "background-color": "blue" }} animate={{ x: 100 }} />
Lifecycle Callbacks
onUpdate
Called on every render with the latest values:
<motion.div animate={{ x: 100 }} onUpdate={(latest) => console.log(latest.x)} />
onAnimationStart / onAnimationComplete
Fired when the animate target starts or finishes:
<motion.div
animate={{ opacity: 1 }}
onAnimationStart={() => console.log("started")}
onAnimationComplete={() => console.log("done")}
/>
Gestures and Drag
Motion supports gesture animations and callbacks:
whileHover- Animation while hoveringwhileTap- Animation while pressingwhileFocus- Animation while focusedwhileInView- Animation when in viewportwhileDrag- Animation while dragging
See Gestures and Drag for details.
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
onTap={() => console.log("clicked")}
/>
Layout
Enable layout animations with layout or layoutId:
// Animate position and size changes
<motion.div layout />
// Shared element transitions
<motion.div layoutId="sidebar" />
See Layout for details.
Server-Side Rendering
On the server, motion components render with deterministic styles:
- Uses
initialstyles if provided - Uses
animatestyles ifinitialisfalseor undefined
// Server renders with opacity: 0
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} />
// Server renders with opacity: 1
<motion.div initial={false} animate={{ opacity: 1 }} />
Limitations
- Custom components via
motion(Component)are not supported yet - MotionValue in
styleprop is planned