← All motion systems
Motion System

Uber Base Design System

Fast, precise motion that inspires confidence — the interface should feel as reliable as the service.

get_motion("uber")
Browse all

Motion System: Uber Base Design System

Category: Transportation / Technology Fast, precise motion that inspires confidence — the interface should feel as reliable as the service.

Motion Philosophy

Uber's product operates at moments of real-world consequence. A rider is standing on a corner in an unfamiliar city. A driver is between trips, checking their next potential fare. These are not contemplative contexts — users need information fast, they need to trust what they see, and they need to act. Motion in the Uber product must serve those needs with precision. It is not there to delight or to entertain; it is there to communicate state changes with the clarity of a signal light.

The system is built around confidence as the emotional register. Transitions are fast and decisive — in the 150–250ms range for most UI interactions — and they use easing curves derived from ease-out-expo that give elements a crisp, authoritative arrival. There is no playfulness in the core product motion language: no bounce, no overshoot, no theatrical flourish. The product handles navigation, payments, and real-world coordination at scale; every motion decision reflects the seriousness of that task.

There is an important distinction in the Base system between driver and rider product motion registers. The rider app permits slightly more expressive motion — map animations, route reveals, driver location pulses — because the rider is in a passive, waiting state where engagement is appropriate. The driver app is more restrained: the driver is operating a vehicle and glancing at a screen. Motion here must be faster, more conservative, and never distracting. The Base system provides the same tokens and patterns to both but documents explicitly which patterns are appropriate for each surface.

Duration Scale

TokenValueUse
duration-instant0msDirect map manipulation, cursor-tracked elements, gesture-following
duration-fast150msHover fills, button press feedback, icon state changes, badge updates
duration-default200msDropdowns, tooltips, small panel transitions, bottom sheet peek
duration-move250msModals, full-panel transitions, tab changes
duration-slow400msMap-level transitions, route reveals, onboarding flows
duration-expressive600msPin drop animation, driver arrival confirmation, trip start sequence

Easing

TokenCurveUse
ease-productivecubic-bezier(0.16, 1, 0.3, 1)Primary UI ease — fast start, smooth precise deceleration
ease-outcubic-bezier(0.0, 0.0, 0.2, 1)Standard element entry
ease-incubic-bezier(0.4, 0.0, 1.0, 1.0)Standard element exit
ease-mapcubic-bezier(0.25, 0.46, 0.45, 0.94)Map camera moves, route reveals — softer for spatial transitions
ease-linearcubic-bezier(0, 0, 1, 1)Loading bars, progress indicators, pulsing location rings

ease-productive is the signature Uber curve. The aggressive initial acceleration (control point at x=0.16) gives transitions a snap that communicates decisiveness and speed — matching the brand promise. This curve at 200ms feels faster than Material's ease-out at the same duration.

Spring Configs (Framer Motion)

Springs are used only for map and location interactions in the core product. General UI chrome uses CSS transitions with ease-productive.

  • Pin drop (location selection on map): stiffness: 380, damping: 28, mass: 0.7 — visible overshoot and bounce, communicates the pin "landing" on the map
  • Map camera snap (re-centering on driver location): stiffness: 200, damping: 28, mass: 1 — gentle, no overshoot; the camera is always moving somewhere purposeful
  • Bottom sheet (pickup address sheet, trip options): stiffness: 300, damping: 35, mass: 1 — slight overshoot on open, snaps cleanly
  • Driver card arrive (driver info panel enters): stiffness: 320, damping: 30, mass: 0.9 — slight bounce to signal the moment of confirmation

No springs in the driver app. The driver-facing components exclusively use CSS transitions with ease-productive for predictability.

Stagger Patterns

  • Trip options (UberX, Comfort, etc.): 30ms between each option card on initial load, entering from bottom
  • Recent places in address search: 20ms between each item
  • Receipt line items: 16ms between each line item when the receipt first renders
  • Surge pricing zones on map: appear simultaneously — zone boundaries are drawn, not staggered
  • Notification list: 25ms between each item

Stagger is applied only on initial mount. Real-time updates (driver location, ETA changes) never use stagger.

Enter / Exit Patterns

Fade + Slide (tooltips, popovers, small menus)

enter: opacity 0→1, translateY 6px→0, duration: duration-default (200ms), ease: ease-productive
exit: opacity 1→0, duration: duration-fast (150ms), ease: ease-in

Bottom Sheet (primary product pattern — address input, trip options, driver info)

enter: translateY 100%→0, spring: Bottom sheet config
exit: translateY 0→100%, duration: duration-move (250ms), ease: ease-in
drag dismiss: follows finger, spring snap back if below threshold, spring dismiss if above

Full-screen overlay (surge map, promo screens)

enter: opacity 0→1, scale 0.98→1, duration: duration-move (250ms), ease: ease-productive
exit: opacity 1→0, duration: duration-fast (150ms), ease: ease-in

Map Route Reveal (route line drawing on map)

stroke-dashoffset animates from full path length → 0, duration: duration-slow (400ms), ease: ease-map
Route line draws from origin toward destination. Simultaneously, camera fits route bounds with spring: Map camera config.

Pin Drop

enter: scale 0→1.3→1.0, spring: Pin drop config. Drop shadow appears at 0ms. Pin bounces once and settles.
confirm (pin tapped): brief scale pulse 1→1.1→1, duration: 200ms, spring: Pin drop at higher stiffness (500)

Trip Status Transition (request → matching → confirmed)

Status pill: crossfade between text states, duration: duration-fast (150ms), ease: ease-productive
Map reconfigures: camera, route, and pin all animate simultaneously using their respective configs
Driver card: enters via Spring Driver card config from bottom

Interaction States

  • Hover (web): Background fill at duration-fast (150ms) ease-productive. No scale on primary action buttons. Icon-only controls get a circular background fill at 150ms.
  • Press/Active: Scale 1→0.97 on primary buttons at duration-fast (150ms) ease-productive, returning to 1.0 at release. On mobile, haptic feedback pairs with press confirmation. Background color darkens by 8% at 0ms.
  • Focus: Focus ring at 2px, brand black #000000, appears at duration-fast (150ms). In reduced-motion or driver contexts, 0ms.
  • Loading (matching state): Pulsing rings radiating from driver pin on map — opacity 0.6→0 over 1200ms linear, looping, 3 rings staggered 400ms apart. Skeleton sheets use gradient shimmer at 1600ms linear infinite.
  • ETA update: Number ticks up or down with a brief translateY transition — old number exits translateY 0→-8px at 100ms ease-in, new number enters translateY 8px→0 at 150ms ease-productive. No opacity change — the motion alone signals the update.
  • Driver location pulse: Circular pulse ring on driver icon, 1400ms linear, infinite, opacity 1→0, scale 1→2.5.
  • Reduced motion: All transforms removed. Opacity fades at 100ms maximum. Pin drop becomes instant scale-in. Map route draws instantly. Bottom sheet snaps in without spring. Driver location pulse stops.

Rules

  • Speed signals confidence. Durations above 300ms are reserved for map-level and trip-confirmation moments. General UI transitions at 200–250ms and hover states at 150ms ensure the interface feels as fast as the service.
  • Springs are for the map, not the chrome. Pin drops, route reveals, and driver location animations benefit from physics because they are representing real-world, physical events. UI chrome — buttons, drawers, menus — uses deterministic CSS transitions.
  • The driver app is a safety-critical surface. Never use expressive springs, bounce, or stagger in driver-facing components. All driver UI motion uses ease-productive CSS transitions at duration-fast (150ms) or duration-default (200ms) maximum.
  • Always implement prefers-reduced-motion. When active, all transforms are disabled, springs snap to end state, map animations are instant, and pulsing location rings stop. The full product must be usable 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("uber")
Set up MCP →