What you will learn

Code Overrides

Overrides are bits of code that you apply to layers on Framer’s canvas. With them, you can use Framer Motion’s animation API and let frames, canvas components, and code components talk to each other.

 

Fades in when appearing, plus has ‘while hover’, ‘while tap’, and ‘while drag’ animations

Add animations

With overrides, you can animate layers without adding extra screens for each animation state.

Create animation sequences, keyframe animations, animations that cycle, staggered animations, and many more.

 

A single override gave this box four animations: When it appears, when you hover over it, when you pick it up, and when you drag it. (View the code)

Add interactivity

Make layers on your canvas talk to each other, whether they’re frames, canvas components, or code components.

You can put the bits of data they need to share in a CreateStore data store.

Separate frames on the canvas communicating through a data store

Enhance canvas components

With overrides, you can change a canvas component’s variables and have it animate between different variants.

 

This example has three canvas components:

  • The ‘Good Morning’ button
  • The ‘Good Night’ button
  • The lamp button

The Good Morning and Good Night buttons can flip the lamp buttons, while the lamp buttons also work independently. The values for the good morning and good night states are saved in a CreateStore data store.

Connect code components

Framer has built-in code components, and you can add others. With overrides, you can change their properties dynamically or let them change other elements on the screen.

A simple example: A Toggle starts and stops Framer’s Ticker component.

In this example, Framer’s Page component makes a Progress component show how far you’ve advanced through the set of pictures.

And the text under the Page component changes depending on the current picture.

Here you can adjust the colors of Framer’s Conic component with Sliders.

Plus: You can change the center point of the Conic’s gradient by tapping it.

Build your own code components

Learn how to build React components for use in Framer projects.

 

Starting from scratch

We start with the simplest possible component.

export default function My_first_component_01() {
    return <h1>Hi there!</h1>
}
import { addPropertyControls, ControlType } from "framer"

const myStyle: React.CSSProperties = {
    height: "100%",
    background: "#09f",
    // Text
    color: "White",
    fontSize: 16,
    fontWeight: 600,
    // Flexbox
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
}

export default function My_first_component_06(props) {
    return <div style={myStyle}>{props.myText}</div>
}

My_first_component_06.defaultProps = {
    myText: "Change my text!",
}

addPropertyControls(My_first_component_06, {
    myText: {
        type: ControlType.String,
        title: "Text",
    },
})

Building it up

Step by step, we add bits of code until the component has CSS styling, a default property, and a property control to change its text.

Property controls

That simple component above has a String property control, but there are other types: Color, Image, Number, File, Boolean, Enum, Fused number, Event handler, Transition, and Component instance. We look at examples for all of them.

Examples of every kind of property control
Examples of all CSS styling techniques

Component styling

We look at the different ways of adding CSS styles to your components: Writing properties inline, putting them in an object, injecting CSS with a <style> tag, or using CSS-in-JS libraries like Styled Components, Emotion, and Stitches.

Component sizing

How to make your components resizable, work well with Framer’s auto-sizing, plus some mistakes you best avoid.

Different kinds of code components and how they’re affected by the size you give them on the canvas
Examples of Motion-compatible components

Motion-compatibility

Make your components react to Framer Motion properties. This way, they can be animated with an override and will respond to whileTap, whileHover, and other events.

Make it smarter

In Smart Code Components, we let components share their internal state and react to property changes.

How to make a component smarter, step by step

Importing other layers, components, and packages

You can enhance your code component by importing other components: canvas components, Framer’s built-in components, components from an existing design system, or a JavaScript library that offers extra functionality.

Importing Framer components

Using JavaScript, Framer’s Time & Date component will always show the current time (or date). I used it here in a recreation of the iOS status bar.

This iOS status bar component has a property control to let you select between Light and Dark modes. The reception, WiFi, and battery icons are SVGs in an (also imported) canvas component with ‘Light’ and ‘Dark’ variants.

Adding a JavaScript library

In this example, I imported the Lodash library of JavaScript utilities and used its flattenDeep() function to clean up a messy array.

Using components from an existing design system

Thanks to Framer’s possibility to import packages directly from NPM, you can reuse existing components. This is a bit more difficult because you might want to:

  • Give a component Property Controls so that you can change how it looks directly in the Properties Panel
  • Make it Motion-compatible (possible with the three design systems I tested)

MUI

I tried a few components from the main Material UI library:

  • A Button (made Motion-compatible so that it works with, for instance, a whileHover)
  • A Rating component
  • Radio buttons
  • A configurable Slider

Chakra UI

And here are some example components from the Chakra UI library.

  • A Button (also made Motion-compatible)
  • A set of Tabs with content
  • A Popover
  • Bottom of the page: A set of ‘Skeleton’ components that have a ‘loading’ state

React Bootstrap

You probably know Bootstrap, a CSS toolkit to quickly build a website. Well, React Bootstrap is the same, but then as React components.

  • A Button (you can make React Bootstrap’s components also Motion-compatible)
  • A Modal that works with a full-page backdrop
  • React Bootstrap’s Carousel component

A full-fledged code component

We apply the gathered knowledge by creating an iOS segmented control.

Ten iterations to get to the finished component

We build it step by step, adding state, animations, resizability, and even some TypeScript.

Here the control shares its selected segment through an override

The finished component knows how to share its internal state (the selected segment).

The three top controls change the properties of the bottom one.

And we ensure that it responds to changes from the outside so that you can change its mode, options, and selected segment at any time.

Use it everywhere

You can use a versatile component like this in any prototype and add it to your Team Library.

Animation

We look at all the possibilities of Framer’s animation API with the aid of 62 example animations.

An overview of the included examples

Most animations are created with simple boxes to clearly show how everything works with the least amount of code.

I provide the examples in two formats:

  • A code overrides version that uses frames drawn on the canvas
  • The same animation as a code component, built with motion elements (like, e.g., <motion.div>)

Plus, there’s a code component version of each example in a CodeSandbox:

A04 – Transform origin
A06 – Complex values

Some of the things that we cover:

Animation sequences

With the useAnimationControls() hook (and also with keyframes), you can create a sequence of animations.

H03 – Sequence
H04 – Sequence with pauses

Animating child frames with variants

Child frames can animate automatically, following their parent, and you can orchestrate these child animations (change the delay between children, the animation direction, etc.).

D02 – Propagation
D03 – Orchestration 1

Tweaking keyframe animations

You can change each keyframe’s animation duration and give them different animation types (easing curve, spring,…).

The first three keyframes take a second, and the last one takes three seconds.
The three animations sequence nicely because each ease ‘out’ is followed by an ease ‘in’.

Animate elements before they’re removed

Framer Motion’s Animate Presence adds something new to React: the possibility to animate elements just before they’re removed from the screen.

Just adding and removing bars makes them animate automatically.
Animating an element in and out by changing its key (slowed down)

Animatable properties

I included examples of how to animate every possible property.

 

There’s more

Next to the examples used to explain everything, there are another 35 animation examples that you can check out for free.

Motion Values

Framer’s animations work with so-called Motion values in the background, independently of React.

You can extract them from an animation and transform them, and you’ll often use them to make an animation follow a drag or scroll movement.

An example of reusing Motion values: The big box has a whileTap animation whose values I extracted to animate the rotatescale, and backgroundColor of the smaller boxes.

Motion values work independently of React. Here’s an example of using ‘state’ (like, e.g., React’s useState()) to change the width of the panels: It doesn’t work as smoothly, and you can’t ‘throw’ the handle.

And here’s a version that uses Motion values: It works much smoother because the animation works independently of React; no React state updates (resulting in a reload) are needed.

The handle’s position gets transformed to width values for the panels with useTransform().

Another example of the useTransform() hook.

Here a Scroll component rotates the boxes on the left: Scrolling 200 pixels results in a 360º rotation.

Plus, as you can see, you can clamp values or add an easing.

A Page component has the same Motion values as a Scroll. Here its horizontal scroll value, contentOffsetX, is used to animate the boxes on the pages.

Scroll-driven animations

With Framer Motion’s useScroll() hook, you can track a web page’s scrolling in three different ways:

  • Track the scrolling of the entire page — Page scroll
  • Track a scrollable element within the page — Element scroll
  • Track where an element currently is in the viewport — Element position

This works in React projects directly in a component, and on Framer Sites pages, you can use code overrides.

Page scroll

Scrolling this page changes:

  • The length of the SVG Path in the top right (+ the value inside it)
  • The position of the box (using CSS’s calc() function)
  • Its gradient (we’re interpolating between two different linear-gradient()s)
  • The box’s border radius (the box becomes a circle and then again a box)
  • The scroll distance value at the bottom of the screen

Element scroll

You can make an element in a webpage scrollable and follow that element’s scroll position.

Element position

There’s a third way to use useScroll(): Elements can track where they are in the browser’s viewport.

Here each picture’s position is used to change its size, opacity, and blur.

Plus, the name of each Buenos Aires barrio has its own effects: its x-position, opacity, and text shadow change.

Animating Motion values

With the animate() function, you can, well,… animate a Motion value. And whatever that Motion value is attached to will follow along.

Animating a Scroll component

Here we’re animating a Scroll with different transition settings:

  • Animating to the top with a duration of 1 second.
  • Animating to 200 using a ‘default spring’ with some extra stiffness.
  • Scrolling to 400 with a ‘duration-based spring’.
  • And to 600 with a custom Bézier curve.

Animating a Page component

Remember that earlier example? Here’s what happens when you animate its contentOffsetX (with some extra added bounciness).

Springy Motion values

With the useSpring() hook, you can create Motion values that will animate to a new value with a spring animation.

You usually create a Motion value with useMotionValue(), but you can also use useSpring(), and then it will be… springy.

Here ‘Rotate’ uses the default useSpring() settings, and ‘Scale’ got some extra stiffness.

You can use the same useSpring() hook to transform a standard Motion value into a bouncier one.

Here, ‘Rotate’ and ‘Scale’ are first converted to horizontal position animations and then made bouncier.

Framer Motion

Most of Framer Motion’s API we already cover in Animation and Motion Values, so in the Framer Motion section, we look at some other things:

  • How to build a React website locally on your computer; or in the browser with CodeSandbox.
  • Framer Motion’s automatic layout animations and shared layout animations
  • The code differences between Framer and Framer Motion
  • SVG animations
  • Using React Router to animate between pages (different URLs on your website)

Making a React website

We install Node.js and use the Create React App package to build a React website on your computer.

Create React App’s default page
CRA’s page with some Framer Motion animations

Layout animations

With the layout property, elements will animate automatically whenever you change their dimensions or position. And withlayoutId, you can animate between entirely separate elements.

Simply changing the knob’s position triggers an animation.
The colored backgrounds are separate elements. Framer Motion automatically animates between them.
A layout animation handles the boxes, while a standard animation changes the background.

Here layout animations are combined with a common background animation.

When the big picture is added, its thumbnail version is automatically hidden.

Simply adding the div with the bigger picture makes it grow automatically from the thumbnail’s position—while the thumbnail is temporarily hidden.

There’s no animation when the children move position or when the parent must change its height.

With the <LayoutGroup> component, you can sync layout animations across a set of elements.

Here’s an example without a layout group: When you tap an element, its siblings will not animate to their new position, and their parent also doesn’t animate to a new size.

Sibling boxes now animate to make space, and the parent fluidly resizes when it needs to grow or shrink.

The <LayoutGroup> wrapper component tracks the layout changes of all elements and has them animate together.

All the boxes now animate to their new position, and their parent also resizes fluidly.

SVG animations

There are many SVG elements, and most of their attributes are animatable. You can, for instance, animate the values of a radial or linear gradient:

The <motion.radialGradient> applied to this <motion.circle> animates in concert with the circle’s position.
Animating a linear gradient’s start and end points

You can animate the shape of an SVG path:

A keyframe sequence between five different path shapes
Four separate paths can form the arcs of a circle.

… but also an SVG path’s offset and length. For example, the animated React logo at the top of this page is a sequence of three animations (and an extra one that continuously rotates the logo).

Shortening the pathLength while moving the pathOffset forward
Changing pathOffset makes the dash travel along the path.
The pathLength grows to 100% with an "easeOut" animation.
The whole SVG rotates continuously (and the gradient also animates).

Routing

The below examples are (mini) websites made in React in which a ‘router’ (here: React Router) shows only one page at a time.

Only routing

Here’s a version with React Router but without animation.

Try the example; you’ll see that each page has its own URL.

With Animate Presence animations

With Animate Presence, you can add animations between the pages.

Using a web API

We create two versions of an icon component that gets its SVG icon from a database on Airtable using their API.

Basic version

First, we make a basic version that merely displays the SVG.

Custom color option

And then a version that lets you change the color of the SVG with some CSS trickery.

Selecting a custom color with the component’s property controls.

Dragging

With a simple override, you can make any layer draggable.

All the settings

With some more code, you can set possible drag directions, keep the draggable frame in an area, or tweak the inertia animation that starts when you release it. We look at all the possible settings.

Snap to grid with modifyTarget()

Snap to grid

Dynamically change the endpoint of the inertia animation to make the frame always move to one of the points on a grid.

Snap to corner with onDragEnd()

Snap to corner

With the onDragEnd() event, you can animate the frame to the nearest corner when it’s released (or the corner you threw it to).

Tap anywhere to make the box snap to that position

Drag controls

You can control a draggable element with the useDragControls() hook.

You can tap anywhere on the background (which uses this hook) to start dragging.

Try to dodge the obstacles using the trackpad.
#SoLongAndThanksForAllTheFish#Starman

… and you can also use drag controls to create a trackpad in a space game.