← All motion systems
Motion System

Airbnb

Warm, unhurried motion that evokes the feeling of exploring somewhere new — generous with time, never rushed.

get_motion("airbnb")
Browse all

Motion System: Airbnb

Category: Travel / Marketplace Warm, unhurried motion that evokes the feeling of exploring somewhere new — generous with time, never rushed.

Motion Philosophy

Airbnb's motion language is an extension of its brand promise: belonging. The product is asking users to trust strangers with their homes and their travels, to book accommodations sight-unseen in cities they have never visited. Motion plays a direct role in building that trust. Transitions are unhurried — not slow, but never rushed. The pace communicates that Airbnb is confident in what it is showing you, and that you have time to look. A design system that snaps through transitions at 100ms feels transactional; Airbnb's motion at 250–350ms feels like someone is presenting something to you with care.

The emotional register of Airbnb's motion is warmth, not efficiency. This distinguishes it from enterprise systems and even from other consumer marketplaces. Airbnb uses Lottie-based vector animations for illustration states — empty states, loading success, confirmation screens — and these animations are notably more expressive and character-filled than what you would find in a utilitarian product. The animation of a heart icon when a listing is saved, the confetti burst on a booking confirmation, the gentle sway of illustrated characters in empty states: these are deliberate choices to make a marketplace feel like a place with personality.

Motion also serves a specific navigational function in Airbnb's product: communicating the richness of listings. Image gallery carousels slide with momentum and follow-through. Map tiles animate in as you pan. The transition from search results into a listing detail page feels expansive — the selected card grows to fill the screen, grounding the user in the context of their choice. These spatial transitions are some of the most carefully crafted in any consumer app, because they carry the weight of the purchase decision: if the transition feels cheap, the product feels cheap.

Duration Scale

TokenValueUse
instant0msDirect manipulation following a touch gesture
fast150msHover states, icon microinteractions, badge updates
default250msMost UI transitions — dropdowns, tooltips, filter chips
slow350msCard expansions, modal open/close, search bar transitions
slower500msHero animations, full-screen photo transitions, onboarding
expressive800ms–1200msLottie confirmation animations, success states, illustration sequences

Easing

TokenCurveUse
ease-outcubic-bezier(0.25, 0.46, 0.45, 0.94)Elements entering — the primary Airbnb easing, slightly softer than standard
ease-incubic-bezier(0.55, 0.055, 0.675, 0.19)Elements exiting the screen
ease-in-outcubic-bezier(0.645, 0.045, 0.355, 1.0)Elements repositioning, carousel slides, map pan transitions
decelerationcubic-bezier(0.0, 0.0, 0.2, 1.0)Cards entering from scroll momentum, elements sweeping in from off-canvas
spring-approximationcubic-bezier(0.34, 1.56, 0.64, 1.0)Subtle overshoot for save/heart interactions and confirmation micro-animations

Airbnb's ease-out is softer than a standard Material or Carbon ease-out. The extra cushion in the early phase gives transitions a slightly more organic, less mechanical quality.

Spring Configs (Framer Motion / react-spring)

Airbnb uses spring physics selectively — primarily for interactive feedback on save actions, photo gallery swipes, and modal drag-to-dismiss gestures. Lottie handles the most expressive animations rather than CSS/JS springs.

  • Default (card expansion, modal sheet): stiffness: 280, damping: 28, mass: 1 — settles cleanly, very slight overshoot acceptable
  • Snappy (interactive gallery swipe, drag dismiss): stiffness: 400, damping: 35, mass: 0.8 — follows gesture velocity, firm settle
  • Gentle (map marker bounce, illustration entrance): stiffness: 160, damping: 20, mass: 1 — visible overshoot, warm and bouncy, for decorative use only
  • Heart / Save: stiffness: 600, damping: 22, mass: 0.6 — quick burst to 1.3 scale then settles to 1.0, paired with haptic feedback

For Lottie animations: use lottie-react or lottie-react-native. Airbnb's open-source Lottie library was developed internally for exactly this use case. Confirmation and success animations are authored in After Effects and rendered as Lottie JSON — do not attempt to replicate these in CSS.

Stagger Patterns

  • Search result cards: 30ms between each card on initial load, starting from the first visible card. Max 8 cards staggered; beyond that, load simultaneously.
  • Filter chips / tags: 20ms between each chip when the filter panel opens, left to right.
  • Photo thumbnails in gallery strip: 25ms between each thumbnail when entering the detail view.
  • Wish list items: 35ms between each listing card, entering from the bottom.
  • Map markers: 40ms stagger from center outward as the map loads, giving a ripple effect from the search origin.

Enter / Exit Patterns

Fade + Slide (default)

enter: opacity 0→1, translateY 8px→0, duration: default (250ms), ease: ease-out
exit: opacity 1→0, translateY 0→-4px, duration: fast (150ms), ease: ease-in

Scale Pop (popovers, tooltips, date picker)

enter: opacity 0→1, scale 0.96→1, duration: default (250ms), ease: ease-out
exit: opacity 1→0, scale 1→0.96, duration: fast (150ms), ease: ease-in

Card Expansion (listing card → detail page)

enter: selected card frame expands to full screen — width/height animate from card bounds to viewport bounds, border-radius 12px→0, duration: slow (350ms), ease: deceleration. Other cards fade out over 150ms.
exit (back): reverse — viewport shrinks back to card frame, border-radius 0→12px, duration: slow (350ms), spring: Snappy. Cards fade back in with 100ms delay.

Image Gallery Carousel

swipe: translateX follows finger directly (no easing during drag). On release: spring: Snappy, settlling to nearest snap point. Velocity is preserved — fast fling snaps further. Thumbnail strip syncs with 50ms lag.

Modal / Bottom Sheet

enter: translateY 100%→0, duration: slow (350ms), spring: Default
exit (tap backdrop): opacity 0 over 200ms, ease: ease-in
exit (swipe dismiss): follows finger, then spring: Snappy to dismiss if velocity threshold met, or snap back if not

Search Bar Expansion (homepage → search mode)

enter: search bar expands from fixed position to full-width overlay, duration: slow (350ms), ease: ease-in-out. Background dims to 0.7 opacity over 250ms. Recent searches slide up from below, staggered 20ms.
exit: reverse collapse, duration: default (250ms), ease: ease-in

Map Listing Cards (bottom sheet with map)

enter: card slides in from bottom edge, translateY 100%→0, duration: default (250ms), ease: ease-out
transition between cards (swipe): spring: Snappy, with new card entering from the direction of swipe

Lottie Success / Confirmation

booking confirmed: Lottie JSON animation, ~1200ms, plays once on mount. No loop. Triggered after API success response. Paired with haptic notification feedback.
heart saved: scale pulse 1→1.3→1, duration: 300ms total, spring: Heart config. Fill color animates from outline to red over 200ms ease-out.

Interaction States

  • Hover: Card shadow deepens (box-shadow elevation increases) over 150ms ease-out. Photos subtly brighten (brightness 1→1.04) over 150ms. No scale on interactive cards by default — the shadow elevation is the primary depth signal. "View photos" overlay appears on image hover with opacity 0→1 over 150ms.
  • Press/Active: Cards scale to 0.98 on mousedown over 100ms ease-out, returning to 1.0 on release via Default spring. On mobile (touchstart), no scale — instant background tint change at 0ms for responsiveness.
  • Focus: Focus ring is a 2px solid #222222 (Airbnb Rausch, the brand red, for high-contrast mode) outline with 2px offset, appearing at 0ms. No animation on focus ring entrance — accessibility takes priority over aesthetics.
  • Loading: Skeleton screens use a shimmer traveling left to right over 1600ms, ease-in-out, looping continuously. The skeleton shapes mirror the actual content layout precisely — card skeletons show the same aspect ratio as listing photos. Airbnb avoids spinners for content areas; spinners appear only for action confirmations (booking, submitting reviews).
  • Map loading: Map tiles fade in from 0→1 opacity over 200ms as they load. Markers scale in from 0→1 with a Gentle spring, staggered 40ms from the map center outward.
  • Reduced motion: When prefers-reduced-motion: reduce, all slide and scale transforms are removed. Transitions become opacity fades at 150ms max. Lottie animations are skipped entirely — show static illustration assets instead. Map marker stagger is disabled; markers appear simultaneously.

Rules

  • Pacing is warmth. Resist shortening durations to feel "snappier." Airbnb's default of 250ms is a deliberate expression of brand pace — a product that feels fast by using 150ms defaults will not feel like Airbnb.
  • Use Lottie for any animation with significant expressiveness — confirmation states, empty states, loading success. Do not attempt to replicate character animation or complex illustration motion in CSS/JS.
  • The card-to-detail expansion transition is the signature animation of the product. It must be smooth, continuous, and spatially grounded. Never use a plain fade or push slide for the listing open transition on capable devices.
  • Hover states use shadow and brightness, not scale. Scale transforms on listing cards cause layout jitter in dense grids. Elevation changes communicate the same depth metaphor without disrupting adjacent elements.
  • Always implement prefers-reduced-motion. Disable Lottie playback and provide static fallbacks for all decorative animations. The product must remain fully usable and emotionally clear without any motion.

Use this in your agent

The DesignMD MCP server returns this full motion system in one call. Combine it with design tokens using get_full_system.

get_full_system("airbnb")
Set up MCP →