Button & CTA Animation Principles
Apply Disney's 12 principles to create buttons that feel alive and responsive.
Principles Applied to Buttons 1. Squash & Stretch
Scale buttons slightly on press: transform: scale(0.95) on :active, return to scale(1) on release. Creates tactile feedback.
- Anticipation
Subtle hover lift before click: transform: translateY(-2px) prepares users for the action.
- Staging
Primary CTAs should be visually prominent. Use size, color contrast, and whitespace. Animate primary buttons more boldly than secondary.
- Straight Ahead & Pose to Pose
Use pose-to-pose for button states: define clear keyframes for default, hover, active, and disabled states.
- Follow Through & Overlapping Action
After click, let shadows or glows settle slightly after the button returns. Icon inside can lag 20-50ms behind button movement.
- Ease In & Ease Out
Never use linear timing. Use ease-out for hover-in (fast start), ease-in for hover-out (gentle exit). cubic-bezier(0.4, 0, 0.2, 1) works well.
- Arcs
Floating action buttons should move in arcs when repositioning. Use transform with easing rather than straight-line movement.
- Secondary Action
Ripple effects, icon rotations, or shadow changes accompany the primary scale/color change. Don't let secondary actions overpower.
- Timing Hover: 150-200ms Active/press: 50-100ms (snappy) Focus ring: 150ms Loading state transition: 200-300ms
- Exaggeration
Success buttons can briefly scale to 1.05 before settling. Error states can include subtle shake (3-5px, 2-3 cycles).
- Solid Drawing
Maintain consistent border-radius and proportions across states. Shadows should respect light source direction throughout.
- Appeal
Round corners feel friendly, sharp corners feel professional. Match button personality to brand. Satisfying click feedback increases conversions.
CSS Implementation .btn { transition: transform 150ms ease-out, box-shadow 150ms ease-out, background-color 150ms ease-out; }
.btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
.btn:active { transform: scale(0.97) translateY(0); transition-duration: 50ms; }
Key Properties transform: scale, translate box-shadow: depth changes background-color: state indication opacity: disabled states filter: brightness on hover