Back to Dictionary
Action Feedback
●○○Ready to Use
Recommended default

Toggle Switch Animation

A sliding thumb across a pill-shaped track, communicating a change in binary state (on/off) with color transitions.

Use

Settings and preference menus

Avoid

Multi-state selections (use radio buttons or segmented controls)

Safer Alternative

No safer default listed.

Risk Level

Low risk

Live Demo

What It Is

A sliding thumb across a pill-shaped track, communicating a change in binary state (on/off) with color transitions.

When to Use

  • Settings and preference menus
  • Enabling/disabling features

When NOT to Use

  • Multi-state selections (use radio buttons or segmented controls)
  • Forms requiring an explicit "Submit" button to save

Configuration Tips

  • 01Animate both the position of the thumb and the background color of the track
  • 02Add a slight stretch/squish to the thumb during motion for a playful feel

You've Seen It In

iOS SettingsVercelTailwind UI

AI Implementation Prompts

Move from a fast scaffold to production details, then tune timing and edge states.

Create an animated toggle switch component.

Reference Implementation

The same implementation approach used by the live preview, kept compact enough to inspect and adapt.

'use client';
import { motion } from 'framer-motion';
import { useState, useEffect } from 'react';

export function ToggleSwitchAnimationDemo({ isPlaying = false }: { isPlaying?: boolean }) {
    const [isOn, setIsOn] = useState(false);

    useEffect(() => {
        if (!isPlaying) {
            setIsOn(false);
            return;
        }

        const interval = setInterval(() => {
            setIsOn((prev) => !prev);
        }, 1500);

        return () => clearInterval(interval);
    }, [isPlaying]);

    const toggleSwitch = () => setIsOn(!isOn);

    return (
        <div className="flex h-64 w-full items-center justify-center rounded-2xl bg-white p-6 shadow-sm ring-1 ring-stone-200">
            <button
                onClick={toggleSwitch}
                className={`relative flex h-8 w-14 cursor-pointer items-center rounded-full p-1 transition-colors duration-300 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-stone-400 focus-visible:ring-offset-2 ${isOn ? 'bg-stone-900' : 'bg-stone-200'
                    }`}
                aria-checked={isOn}
                role="switch"
            >
                <span className="sr-only">Toggle setting</span>
                <motion.div
                    animate={{ x: isOn ? 24 : 0 }}
                    transition={{ type: 'spring', stiffness: 500, damping: 30 }}
                    className="h-6 w-6 rounded-full bg-white shadow-sm"
                />
            </button>
        </div>
    );
}