Motion+

Material Design: Ripple

An example of creating a press ripple with Motion for React, inspired by Google Material Design.

Time
5 min
Difficulty
Beginner
Access
Motion+
>Live exampleOpen in new tab

The Material Design Ripple example recreates the touch ripple effect found in Google's Material Design components. The ripple creates visual feedback when users interact with a button, expanding outward from the point of touch.

In this tutorial, we'll use three Motion for React APIs: the motion component for gesture handling, AnimatePresence for exit animations, and the whileHover prop for hover states.

Get started

Let's start with a simple button component and the basic structure we need for the ripple effect:

"use client"

import { useState, useRef, useCallback } from "react"

export default function MaterialDesignRipple() {
    return (
        <>
            <button className="md-button">
                Click me
                <span className="ripple-container" aria-hidden>
                    {/* Ripples will be rendered here */}
                </span>
            </button>

            <Stylesheet />
        </>
    )
}

function Stylesheet() {
    return <style>{`/** Copy from example source */`}</style>
}

The key to our ripple setup is the .ripple-container element inside the button. This acts as a clipping mask - any ripples we create will be contained within the button's rounded corners.

We'll need to track multiple ripples in state since users can create overlapping ripples with rapid interactions:

const [ripples, setRipples] = useState([])
const buttonRef = useRef(null)
const idRef = useRef(0)

Each ripple needs a unique ID for React's key prop, so we'll use a ref to track our ID counter.