Motion
popcn/ui includes a comprehensive motion system designed for GenZ aesthetics. Bouncy, playful animations that feel responsive and delightful without being distracting.
Animation Tokens
Customize timing and easing through CSS custom properties.
:root {
/* Duration tokens */
--ap-dur-1: 100ms; /* Micro: button press */
--ap-dur-2: 200ms; /* Quick: pop, snap */
--ap-dur-3: 300ms; /* Standard: most transitions */
--ap-dur-4: 500ms; /* Emphasis: entrance animations */
--ap-dur-5: 800ms; /* Dramatic: confetti, sequences */
/* Easing tokens */
--ap-ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
--ap-ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
--ap-ease-snap: cubic-bezier(0.2, 0, 0, 1);
--ap-ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
/* Motion control */
--ap-motion: 1; /* 1=enabled, 0=disabled */
--ap-motion-scale: 1; /* Intensity multiplier */
}定常モーションとクリック時モーション
motionIdle(定常)は float / shine / wave のように常時再生、motionClick(クリック時)は pop / snap / bounce / wiggle / jelly のようにクリックで発火します。 両方指定して組み合わせられます。
<Button motionIdle="shine" motionClick="pop">shine + pop</Button>
<Button motionIdle="wave" motionClick="bounce">wave + bounce</Button>Motion Presets
motion で従来どおり一括指定も可能です。 定常とクリック時を分けたい場合は motionIdle / motionClick を使ってください。
<Button motion="pop">Pop</Button>
<Button motion="bounce">Bounce</Button>
<Button motion="wiggle">Wiggle</Button>
<Button motion="jelly">Jelly</Button>
<Button motion="float">Float</Button>
<Button motion="shine">Shine</Button>
<Button motion="wave">Wave</Button>
<Button motion="snap">Snap</Button>
<Button motion="none">None</Button>Motion Details
Default motion preset
Quick scale bounce on click. Satisfying feedback that feels responsive.
<Button motion="pop" />Vertical bounce with scale
Playful vertical bounce combined with subtle scaling. Perfect for likes, notifications, and celebratory actions.
<Button motion="bounce" />Horizontal shake animation
Attention-grabbing horizontal shake. Great for error states or drawing user attention.
<Button motion="wiggle" />Elastic squash and stretch
Playful jelly-like deformation. Adds a fun, bouncy character to interactions.
<Button motion="jelly" />Continuous gentle hover
Subtle floating animation that draws attention. Best for CTAs and featured actions.
<Button motion="float" />Gradient sweep effect
::before の光の帯が左端から右端へ約2.5秒でスイープするループアニメーションです。常時動くため、クリック時の pop や bounce より控えめで、プライマリボタンにさりげないきらめきを足したいときに使います。
<Button motion="shine" />Gradient wave effect
グラデーションの背景位置を波のように動かすループアニメーションです。約4秒かけてグラデーションが上下左右にゆらめき、有機的な動きを生み出します。常時動くため、控えめなアクセントとして使えます。
<Button motion="wave" />Instant press feedback
Immediate scale reduction on press. Creates tactile button-press feel.
<Button motion="snap" />Utility Classes
Pre-built utility classes for common animation patterns.
Hover Effects
.ap-hover-floatHover to see the float effect
.ap-hover-scaleHover to see the scale effect
.ap-hover-glowHover to see the glow effect
.ap-hover-tiltHover to see the tilt effect
Active Effects
.ap-active-squishClick and hold to see the squish effect
.ap-active-pressClick and hold to see the press effect
Enter/Exit Animations
.ap-enter-popScale from 0.9 with fade
.ap-enter-slideSlide up from below
.ap-enter-bounceBouncy entrance
.ap-enter-jellyElastic jelly entrance
/* Transition presets */
.ap-trans-pop /* Bouncy transition */
.ap-trans-snap /* Sharp transition */
.ap-trans-soft /* Soft transition */
.ap-trans-spring /* Elastic transition */
/* Hover effects */
.ap-hover-float /* Float up on hover */
.ap-hover-glow /* Glow on hover */
.ap-hover-scale /* Scale up on hover */
.ap-hover-tilt /* Tilt on hover */
/* Active effects */
.ap-active-squish /* Squish on press */
.ap-active-press /* Press down on click */
/* Enter animations */
.ap-enter-pop /* Pop in */
.ap-enter-slide /* Slide up */
.ap-enter-bounce /* Bounce in */
.ap-enter-jelly /* Jelly in */
/* Exit animations */
.ap-exit-fade /* Fade out */
.ap-exit-slide /* Slide down */
/* Special effects */
.ap-wiggle /* Shake animation */
.ap-pulse-ring /* Ripple effect */
.ap-confetti /* Celebration */Card Motion Variants
Cards support motion variants for interactive hover effects.
Float
motion="float"
Scale
motion="scale"
Tilt
motion="tilt"
Glow
motion="glow"
<Card motion="float">Float on hover</Card>
<Card motion="scale">Scale on hover</Card>
<Card motion="tilt">Tilt on hover</Card>
<Card motion="glow">Glow on hover</Card>Tailwind Configuration
Extend your Tailwind config to include the animation utilities.
// tailwind.config.ts
export default {
theme: {
extend: {
keyframes: {
"ap-bounce": {
"0%, 100%": { transform: "translateY(0) scale(1)" },
"30%": { transform: "translateY(-8px) scale(1.02)" },
"50%": { transform: "translateY(-4px) scale(1)" },
"70%": { transform: "translateY(-2px) scale(1.01)" },
},
"ap-wiggle": {
"0%, 100%": { transform: "translateX(0)" },
"10%, 30%": { transform: "translateX(-4px)" },
"20%, 40%": { transform: "translateX(4px)" },
// ... shake pattern
},
"ap-jelly": {
"0%": { transform: "scale(1, 1)" },
"25%": { transform: "scale(0.95, 1.05)" },
"50%": { transform: "scale(1.05, 0.95)" },
"75%": { transform: "scale(0.98, 1.02)" },
"100%": { transform: "scale(1, 1)" },
},
// ... more keyframes
},
animation: {
"ap-bounce": "ap-bounce var(--ap-dur-3) var(--ap-ease-pop)",
"ap-wiggle": "ap-wiggle var(--ap-dur-4) var(--ap-ease-snap)",
"ap-jelly": "ap-jelly var(--ap-dur-3) var(--ap-ease-spring)",
// ... more animations
},
transitionDuration: {
"ap-1": "var(--ap-dur-1)",
"ap-2": "var(--ap-dur-2)",
"ap-3": "var(--ap-dur-3)",
"ap-4": "var(--ap-dur-4)",
"ap-5": "var(--ap-dur-5)",
},
transitionTimingFunction: {
"ap-pop": "var(--ap-ease-pop)",
"ap-soft": "var(--ap-ease-soft)",
"ap-snap": "var(--ap-ease-snap)",
"ap-spring": "var(--ap-ease-spring)",
},
},
},
}Accessibility
popcn/ui respects user motion preferences and provides multiple ways to control animations.
1. System Preference
Automatically respects prefers-reduced-motion. When enabled, --ap-motion is set to 0.
2. CSS Variable Control
Set --ap-motion: 0 to disable animations programmatically. Use --ap-motion-scale to adjust intensity (0.5 = subtle, 1 = normal).
3. Utility Class
Add .ap-motion-reduce to any element to disable animations for that subtree. Alternatively, use .ap-no-motion on the root.
4. Functionality Preserved
All interactive elements remain fully functional without animations. Visual feedback through color changes and focus states is maintained.
/* System preference auto-detection */
@media (prefers-reduced-motion: reduce) {
:root {
--ap-motion: 0;
--ap-motion-scale: 0;
}
}
/* Manual disable class */
.ap-no-motion {
--ap-motion: 0;
}
/* Disable for specific section */
.ap-motion-reduce,
.ap-motion-reduce * {
--ap-motion: 0 !important;
animation: none !important;
transition-duration: 0.01ms !important;
}
/* Adjust intensity without fully disabling */
.subtle-motion {
--ap-motion-scale: 0.5;
}Best Practices
Use meaningful motion: Animation should provide feedback, not just decoration. Pop for clicks, wiggle for errors, bounce for success.
Keep it subtle: GenZ aesthetics favor quick, bouncy animations. Use --ap-dur-2 (200ms) for most interactions.
Combine wisely: Hover effects + click animations work great together. Avoid combining multiple continuous animations.
Test with reduced motion: Always verify your UI works with animations disabled. Use the toggle at the top of this page to test.