Press

Matt Perry

In this tutorial, we're going to build the Press example step-by-step.

This tutorial is rated beginner difficulty, which means we'll spend some time explaining the Motion APIs that we've chosen to use (and why), and also any browser APIs we encounter that might be unfamiliar to beginners.

Here's a live demo of the example we're going to be creating:

Loading...

Introduction

The Press example shows how to create an interactive button that responds to user presses with spring animations. This example uses two key APIs from Motion:

  • The press function detects when users press down and release on an element

  • The animate function creates smooth animations

Motion's press function automatically handles important details for you - it filters out right clicks and secondary touch points, and makes every element keyboard accessible by default. This means your interactive elements work great for all users without extra code.

Get started

Let's start with the basic HTML and CSS for a simple box element:

<div class="box"></div>

<style>
    /** Copy styles from example source code */
<

The .box:focus-visible styles ensure keyboard users can see when the box is focused. This is important for accessibility.

Let's animate!

Import from Motion

First, import the press and animate functions from Motion:

<script type="module">
    import { animate, press } from "motion"
</script>

Add the press gesture

Now we can use the press function to detect when users interact with the box. The press function takes two arguments: a CSS selector (or element) and a callback function that runs when the press starts:

press(".box", (element) => {
    // This runs when the user presses down
})

The callback receives the element being pressed as its first argument.

Animate on press

When the user presses down, we want to scale the box down to 0.8 using a spring animation. Add this animation inside the callback:

press(".box", (element) => {
    animate(element, { scale: 0.8 }, { type: "spring", stiffness: 1000 })
})

The animate function takes three arguments:

  • The element to animate

  • The target values (in this case, scale: 0.8)

  • Animation options (we're using a spring with high stiffness for a snappy feel)

Animate on release

The press callback can return a function that runs when the user releases. This is where we'll animate the box back to its original size:

press(".box", (element) => {
    animate(element, { scale: 0.8 }, { type: "spring", stiffness: 1000 })

    return () =>
        animate(element, { scale: 1 }, { type: "spring", stiffness: 500 })
})

Notice the release animation uses a lower stiffness value of 500. This makes the box spring back a bit more slowly, creating a nice bouncy effect.

Conclusion

We've built an interactive button with press animations using Motion's press and animate functions. The press function automatically handles cross-platform touch and mouse events, filters out unwanted interactions, and ensures keyboard accessibility - all without any extra code from us. By using spring animations with different stiffness values for press and release, we created a tactile, responsive feel that makes the button satisfying to interact with.

Motion is supported by the best in the industry.