# Frame
The basic container for layout, styling, animation and events.The Frame
component is a div
with extra options and opinionated defaults to get things done more quickly. The top level props just generate style
for the underlying div
, but you always override any styling with the style
prop. Frames allow you to do the following.
- Set sizes and add layout constraints.
- Center horizontally or vertically.
- Change colors or background images.
- Animate between states (variants).
- Add tap events that work on desktop and mobile.
- Add advanced behavior like dragging.
- Respond to advanced gestures like pan.
import * as React from "react"
import { Frame } from "framer"
export function MyComponent() {
return (
<Frame size={300} center>
Hello
</Frame>
)
}
# Performance
To get the most performance from your animations, try to only animate transform values and opacity, as they are GPU-accelerated. This way, you can animate hundreds of layers on modern mobile devices.
// GPU accelerated (fast)
<Frame initial={{scale: 1}} animate={{scale: 2}} />
// CPU drawing (slower)
<Frame initial={{size: 200}} animate={{size: 400}} />
# Integration
The Frame component was designed to play nice with any DOM element, mainly because it is a DOM element (regular div
) itself. You can use any layout combination between size
, width
, height
, top
, right
, bottom
, left
and center
.
Here’s an example of a complicated dynamic layout that uses variable, fixed and centered layout right inside a parent div
.
export function MyComponent(props) {
return (
<div
style={{
width: "100%",
height: "100%",
background: "rgba(255, 0, 0, .5)",
}}
>
<Frame size="40%" center="x" top={50}>
Hello
</Frame>
</div>
)
}
# Text Centering
If your Frame
only contains text contents, it will be centered by default for convenience. You can avoid this behavior by wrapping the text in a span
element.
// Text contents will be centered
<Frame>Hello</Frame>
// Text contents will not be centered
<Frame><span>Hello</span></Frame>
# Event Handling
Event propagation is handled by React and behaves like DOM events. You can cancel events with preventDefault()
and stop propagation with stopPropagation()
.
# DOM
The Frame
component is based on an HTML div
so it inherits all DOM properties using camelCasing.
// CSS classes
<Frame className="pretty" />
// DOM events
<Frame onClick={onClick} />
<Frame onMouseOut={onMouseOut} />
<Frame onTouchUp={onTouchUp} />
# Layout
Layout rules for Frame
behave like regular CSS, and re-layout if the parent element (Frame
or div
) resizes. You can optionally use handy shortcuts like center
to quickly center elements in their parent.
Frames are positioned absolute
by default. You can explicitly change this with the position
property. If you add a Frame as a child of a component that expects relative
layout (like Stack
), that component may override the position
to relative
automatically, for convenience.
When the combination of layout properties is incompatible, the override order is consistent with CSS. The x
and y
transforms always work, as they are applied after the normal layout rules are set.
height
>top
,bottom
>center=“y”
width
>left
,right
>center=“x”
// Right is ignored
<Frame width={100} left={100} right={100} />
// Center is ignored
<Frame left={0} right={100} center="x" />
# width: number | string | MotionValue<number | string>
Set the CSS width
property. Set to 200
by default. Accepts all CSS value types (including pixels, percentages, keywords and more).
// Pixels
<Frame width={100} />
// Percentages
<Frame width={"100%"} />
# height: number | string | MotionValue<number | string>
Set the CSS height
property. Set to 200
by default. Accepts all CSS value types (including pixels, percentages, keywords and more).
// Pixels
<Frame height={100} />
// Percentages
<Frame height={"100%"} />
# size: number | string
Shortcut for setting the width and height simultaneously.
<Frame size={100} />
# top: number | string | MotionValue<number | string>
Distance from the top in pixels. Set to 0
by default.
<Frame top={100} />
# right: number | string | MotionValue<number | string>
Distance from the right in pixels. Set to 0
by default.
<Frame right={100} />
# bottom: number | string | MotionValue<number | string>
Distance from the bottom in pixels. Set to 0
by default.
<Frame bottom={100} />
# left: number | string | MotionValue<number | string>
Distance from the left in pixels. Set to 0
by default.
<Frame left={100} />
# center: boolean | "x" | "y"
Shortcut for centering Frames.
// Center
<Frame center />
// Center horizontally
<Frame center="x" />
// Center vertically
<Frame center="y" />
# position: string
Set the CSS position
property. Set to "absolute"
by default.
<Frame position={"relative"} />
# Visual
# style: MotionStyle
The React DOM style
prop, useful for setting CSS properties that aren't explicitly exposed by Frame
props.
<Frame style={{ mixBlendMode: "difference" }} />
# visible: boolean
Defines whether or not the Frame
is visible. Unlike opacity
, this property cannot be animated. Set to true
by default. Maps to CSS.
<Frame visible={false} />
# opacity: number | MotionValue<number>
Set the opacity value, which allows you to make elements semi-transparent or entirely hidden. Useful for show-and-hide animations. Set to 1
by default.
<Frame opacity={0.5} />
# background: Background | null
Set the background of a Frame
. Supports color strings, color objects and images by using src
. Set to a semi-transparent blue color by default. This will override the values set by the image
property. To use a color and a image, use backgroundColor
instead
<Frame background="#09F"/>
<Frame background={Color({r: 255, g: 0, b: 102})} />
<Frame background={{ alpha: 1, angle: 75, start: "#09F", end: "#F09"}} />
<Frame background={{ src: "https://example.com/logo.png"}} />
# backgroundColor: string | Color
Set the background color of a Frame
. Supports color strings and objects. Use this property to set a background color alongside the image
property.
<Frame backgroundColor="#09F"/>
<Frame backgroundColor={Color({r: 255, g: 0, b: 102})} />
# image: string
Sets a background image of a Frame
. Will wrap the passed value in a url('')
if needed.
<Frame image="https://source.unsplash.com/random" />
# color: string | MotionValue<string>
Set the color for text elements inside of a Frame
. By default, text within Frames will be rendered in black.
<Frame color="#09F" />
# border: string | MotionValue<string>
Set the CSS border property, which accepts width, style and color. Set to "none"
by default.
<Frame border="1px solid #09F" />
# radius: number | string | MotionValue<number | string>
Set the CSS border-radius property, in pixels or percentages. Set to 0
by default.
// Radius with pixels
<Frame radius={10} />
// Radius with percentages
<Frame radius="50%" />
# shadow: string | MotionValue<string>
Set the CSS box-shadow property.
<Frame shadow="10px 5px 5px black" />
# overflow: "visible" | "hidden"
Set the CSS overflow property. Set to "visible"
by default.
<Frame overflow="hidden" />
# Transform
Transform properties are accelerated by the GPU and therefore animate smoothly. They are directly mapped to their CSS transform()
counterparts, so x = 200
becomes transform: translateX(200)
. The transformations are applied after the normal layout rules.
The exact order how the transforms are applied is: translate
, scale
, rotate
and skew
. You can customize the order using transformTemplate
.
<Frame
x={100}
y={100}
z={100}
rotate={90}
scale={1.2}
skew={15}
/>
# x: number | string | MotionValue<number | string>
Set the CSS transform translateX
property.
<Frame x={100} />
# y: number | string | MotionValue<number | string>
Set the CSS transform translateY
property.
<Frame y={100} />
# z: number | string | MotionValue<number | string>
Set the CSS transform translateZ
property.
<Frame z={100} />
# rotate: number | string | MotionValue<number | string>
Set the CSS transform rotate
property in degrees.
<Frame rotate={45}/>
# rotateX: number | string | MotionValue<number | string>
Set the CSS transform rotateX
property in degrees.
<Frame rotateX={45}/>
# rotateY: number | string | MotionValue<number | string>
Set the CSS transform rotateY
property in degrees.
<Frame rotateY={45}/>
# rotateZ: number | string | MotionValue<number | string>
Set the CSS transform rotateZ
property in degrees.
<Frame rotateZ={45}/>
# scale: number | string | MotionValue<number | string>
Set the CSS transform scale
property.
<Frame scale={1.5} />
# scaleX: number | string | MotionValue<number | string>
Set the CSS transform scaleX
property.
<Frame scaleX={1.5} />
# scaleY: number | string | MotionValue<number | string>
Set the CSS transform scaleY
property.
<Frame scaleY={2} />
# skew: number | string | MotionValue<number | string>
Set the CSS transform skew
property in degrees.
<Frame skew={15} />
# skewX: number | string | MotionValue<number | string>
Set the CSS transform skewX
property in degrees.
<Frame skewX={15} />
# skewY: number | string | MotionValue<number | string>
Set the CSS transform skewY
property in degrees.
<Frame skewY={15} />
# originX: number | string | MotionValue<number | string>
Set the CSS transform originX
property.
<Frame originX={0.5} />
# originY: number | string | MotionValue<number | string>
Set the CSS transform originY
property.
<Frame originY={0.5} />
# originZ: number | string | MotionValue<number | string>
Set the CSS transform originZ
property. Defaults to px
units.
<Frame originZ={100} />
# perspective: number | string | MotionValue<number | string>
Set the CSS perspective property.
<Frame perspective={500} />
# preserve3d: boolean
Position the children of the frame in 3D space. Set to false
by default.
<Frame preserve3d={true} />
# backfaceVisible: boolean
Sets whether the back face is visible when turned towards the user. Set to true
by default.
<Frame backfaceVisible={true} />
# transformTemplate(transform, generatedTransform): string
By default, Framer Motion generates a transform
property with a sensible transform order. transformTemplate
can be used to create a different order, or to append/preprend the automatically generated transform
property.
function transformTemplate({ x, rotate }) {
return `rotate(${rotate}deg) translateX(${x}px)`
}
<Frame x={0} rotate={180} transformTemplate={transformTemplate} />
transform: TransformProperties The latest animated transform props. |
---|
generatedTransform: string The transform string as automatically generated by Framer Motion |
returns: string |
# Animation
The following are properties accepted by the Frame
component for animation, in addition to its standard properties. When animation properties are combined, they become very flexible and powerful.
# initial: boolean | Target | VariantLabels
Properties, variant label or array of variant labels to start in.
Set to false
to initialise with the values in animate
(disabling the mount animation)
// As values
<Frame initial={{ opacity: 1 }} />
// As variant
<Frame initial="visible" variants={variants} />
// Multiple variants
<Frame initial={["visible", "active"]} variants={variants} />
// As false (disable mount animation)
<Frame initial={false} animate={{ opacity: 0 }} />
# animate: AnimationControls | TargetAndTransition | VariantLabels | boolean
Values to animate to, variant label(s), or AnimationControls
.
// As values
<Frame animate={{ opacity: 1 }} />
// As variant
<Frame animate="visible" variants={variants} />
// Multiple variants
<Frame animate={["visible", "active"]} variants={variants} />
// AnimationControls
<Frame animate={animation} />
# exit: TargetAndTransition | VariantLabels
A target to animate to when this component is removed from the tree.
This component **must** be the first animatable child of an AnimatePresence
to enable this exit animation.
This limitation exists because React doesn't allow components to defer unmounting until after an animation is complete. Once this limitation is fixed, the AnimatePresence
component will be unnecessary.
import { Frame, AnimatePresence } from 'framer'
export function MyComponent(props) {
return (
<AnimatePresence>
{props.isVisible && (
<Frame
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
</AnimatePresence>
)
}
# transition: Transition
Default transition. If no transition
is defined in animate
, it will use the transition defined here.
const spring = {
type: "spring",
damping: 10,
stiffness: 100
}
<Frame transition={spring} animate={{ scale: 1.2 }} />
# onUpdate(latest): void
Callback with latest motion values, fired max once per frame.
function onUpdate(latest) {
console.log(latest.x, latest.opacity)
}
<Frame animate={{ x: 100, opacity: 0 }} onUpdate={onUpdate} />
latest: ResolvedValues |
---|
# onAnimationStart(): void
Callback when animation defined in animate
begins.
function onStart() {
console.log("Animation started")
}
<Frame animate={{ x: 100 }} onAnimationStart={onStart} />
# onAnimationComplete(definition): void
Callback when animation defined in animate
is complete.
The provided callback will be called the triggering animation definition. If this is a variant, it'll be the variant name, and if a target object then it'll be the target object.
This way, it's possible to figure out which animation has completed.
function onComplete() {
console.log("Animation completed")
}
<Frame
animate={{ x: 100 }}
onAnimationComplete={definition => {
console.log('Completed animating', definition)
}}
/>
definition: AnimationDefinition |
---|
# Transition
The transition
property can be used to customize animations directly on a Frame
. A transition
typically defines a single transition that applies to all animating values on that Frame
. It’s possible to override this transition
property if a transition is added to an object or variants
label given to the animate
, hover
or press
properties.
<Frame
animate={{ scale: 0.5 }}
transition={{ ease: "easeOut" }}
/>
You can also define a seperate transition for each animating value on the Frame
. Any properties left unspecified will use a default transition.
const transition = {
x: { type: "spring", stiffness: 400 },
opacity: { ease: "easeIn" },
}
To override the default transition
, when defining separate transitions for each animating value, you can override the default
property.
const transition = {
x: { type: "keyframes", values: [0, 100, 0] },
default: { duration: 0.5 },
}
You can add orchestration properties like delay
to affect the whole animation. The numeric value represents seconds.
const transition = {
delay: 1,
opacity: { duration: 0.5 },
}
The transition
property can also be specified inside your variants object and then passed to your Frame
using the variants
property.
const variants = {
hidden: {
opacity: 0,
transition: { duration: 0.25 },
},
visible: { opacity: 1 },
}
# Variants
Variants are an advanced way to organize your animation states by name.
# variants: Variants
Variants allow you to define animation states and organise them by name. They allow you to control animations throughout a component tree by switching a single animate
prop.
Using transition
options like delayChildren
and staggerChildren
, you can orchestrate when children animations play relative to their parent.
After passing variants to one or more Frame
's variants
prop, these variants can be used in place of values on the animate
, initial
, whileFocus
, whileTap
and whileHover
props.
const variants = {
active: {
backgroundColor: "#f00"
},
inactive: {
backgroundColor: "#fff",
transition: { duration: 2 }
}
}
<Frame variants={variants} animate="active" />
# Tap
The tap gesture detects when a pointer presses down and releases on the same component.
It fires an tap
event when tapping successfully completes on an component, and a tapCancel
event when tapping ends outside the component.
If the tappable component is a child of a draggable component, it'll automatically cancel the tap gesture if the pointer moves further than 3 pixels during the gesture.
# whileTap: VariantLabels | TargetAndTransition
Properties or variant label to animate to while the component is pressed.
<Frame whileTap={{ scale: 0.8 }} />
# onTap(event, info): void
Callback when the tap gesture successfully ends on this element.
function onTap(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onTap={onTap} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: TapInfo An |
# onTapStart(event, info): void
Callback when the tap gesture starts on this element.
function onTapStart(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onTapStart={onTapStart} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: TapInfo An |
# onTapCancel(event, info): void
Callback when the tap gesture ends outside this element.
function onTapCancel(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onTapCancel={onTapCancel} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: TapInfo An |
# Hover
The hover gesture detects when a pointer hovers over or leaves a component.
It differs from onMouseEnter
and onMouseLeave
in that hover is guaranteed to only fire as a result of actual mouse events (as opposed to browser-generated mice events emulated from touch input).
# whileHover: VariantLabels | TargetAndTransition
Properties or variant label to animate to while the hover gesture is recognised.
<Frame whileHover={{ scale: 1.2 }} />
# onHoverStart(event, info): void
Callback function that fires when pointer starts hovering over the component.
function onHoverStart(event) {
console.log("Hover starts")
}
<Frame onHoverStart={onHoverStart} />
event: MouseEvent |
---|
info: EventInfo |
# onHoverEnd(event, info): void
Callback function that fires when pointer stops hovering over the component.
function onHoverEnd(event) {
console.log("Hover ends")
}
<Frame onHoverEnd={onHoverEnd} />
event: MouseEvent |
---|
info: EventInfo |
# Pan
The pan gesture recognises when a pointer presses down on a component and moves further than 3 pixels. The pan gesture is ended when the pointer is released.
# onPan(event, info): void
Callback function that fires when the pan gesture is recognised on this element.
- Note:
- For pan gestures to work correctly with touch input, the element needs touch scrolling to be disabled on either x/y or both axis with the [touch
- action](https://developer.mozilla.org/en
- US/docs/Web/CSS/touchaction) CSS rule.
function onPan(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onPan={onPan} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: PanInfo A
|
# onPanStart(event, info): void
Callback function that fires when the pan gesture begins on this element.
function onPanStart(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onPanStart={onPanStart} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: PanInfo A
|
# onPanEnd(event, info): void
Callback function that fires when the pan gesture ends on this element.
function onPanEnd(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onPanEnd={onPanEnd} />
event: MouseEvent | TouchEvent | PointerEvent The originating pointer event. |
---|
info: PanInfo A
|
# Drag
The drag gesture follows the rules of the pan gesture but applies pointer movement to the x and/or y axis of the component.
# onDrag(event, info): void
Callback function that fires when the component is dragged.
function onDrag(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame drag onDrag={onDrag} />
event: MouseEvent | TouchEvent | PointerEvent |
---|
info: PanInfo |
# onDragStart(event, info): void
Callback function that fires when dragging starts.
function onDragStart(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame drag onDragStart={onDragStart} />
event: MouseEvent | TouchEvent | PointerEvent |
---|
info: PanInfo |
# onDragEnd(event, info): void
Callback function that fires when dragging ends.
function onDragEnd(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame drag onDragEnd={onDragEnd} />
event: MouseEvent | TouchEvent | PointerEvent |
---|
info: PanInfo |
# onDirectionLock(axis): void
Callback function that fires a drag direction is determined.
function onDirectionLock(axis) {
console.log(axis)
}
<Frame
drag
dragDirectionLock
onDirectionLock={onDirectionLock}
/>
axis: "x" | "y" |
---|
# drag: boolean | "x" | "y"
Enable dragging for this element. Set to false
by default. Set true
to drag in both directions. Set "x"
or "y"
to only drag in a specific direction.
<Frame drag="x" />
# dragConstraints: false | Partial<BoundingBox2D> | RefObject<Element>
Applies constraints on the permitted draggable area.
It can accept an object of optional top
, left
, right
, and bottom
values, measured in pixels. This will define a distance the named edge of the draggable component.
Alternatively, it can accept a ref
to another component created with React's useRef
hook. This ref
should be passed both to the draggable component's dragConstraints
prop, and the ref
of the component you want to use as constraints.
// In pixels
<Frame
drag="x"
dragConstraints={{ left: 0, right: 300 }}
/>
// As a ref to another component
function MyComponent() {
const constraintsRef = useRef(null)
return (
<Frame ref={constraintsRef} width={400} height={400}>
<Frame drag dragConstraints={constraintsRef} />
</Frame>
)
}
# dragElastic: DragElastic
The degree of movement allowed outside constraints. 0 = no movement, 1 = full movement.
Set to 0.5
by default. Can also be set as false
to disable movement.
By passing an object of top
/right
/bottom
/left
, individual values can be set per constraint. Any missing values will be set to 0
.
<Frame
drag={true}
dragConstraints={{ left: 0, right: 300 }}
dragElastic={0.2}
/>
# dragMomentum: boolean
Apply momentum from the pan gesture to the component when dragging finishes. Set to true
by default.
<Frame
drag={true}
dragConstraints={{ left: 0, right: 300 }}
dragMomentum={false}
/>
# dragTransition: InertiaOptions
Allows you to change dragging inertia parameters. When releasing a draggable Frame, an animation with type inertia
starts. The animation is based on your dragging velocity. This property allows you to customize it. See Inertia for all properties you can use.
<Frame
drag={true}
dragTransition={{ bounceStiffness: 600, bounceDamping: 10 }}
/>
# dragPropagation: boolean
Allows drag gesture propagation to child components. Set to false
by default.
<Frame drag="x" dragPropagation={true} />
# Types
# TapInfo
Passed in to tap event handlers like onTap
the TapInfo
object contains information about the tap gesture such as it‘s location.
function onTap(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onTap={onTap} />
# point: Point2D
Contains x
and y
values for the tap gesture relative to the device or page.
function onTapStart(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onTapStart={onTapStart} />
# PanInfo
Passed in to pan event handlers like onPan
the PanInfo
object contains information about the current state of the tap gesture such as its point
, delta
, offset
and velocity
.
function onPan(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onPan={onPan} />
# delta: Point2D
Contains x
and y
values for the distance moved since the last event.
function onPan(event, info) {
console.log(info.delta.x, info.delta.y)
}
<Frame onPan={onPan} />
# offset: Point2D
Contains x
and y
values for the distance moved from the first pan event.
function onPan(event, info) {
console.log(info.offset.x, info.offset.y)
}
<Frame onPan={onPan} />
# point: Point2D
Contains x
and y
values for the current pan position relative to the device or page.
function onPan(event, info) {
console.log(info.point.x, info.point.y)
}
<Frame onPan={onPan} />
# velocity: Point2D
Contains x
and y
values for the current velocity of the pointer.
function onPan(event, info) {
console.log(info.velocity.x, info.velocity.y)
}
<Frame onPan={onPan} />