Blog · September 11, 2026

How to add motion without it feeling gimmicky.

A bounce on one button feels alive. The same bounce on every button, card, and toast in the app feels like a UI kit demo. The line between motion that reads as polish and motion that reads as gimmick isn't taste — it's a short list of physical rules that almost every well-regarded app follows without ever writing them down.

Motion has exactly three jobs

Feedback: confirm that an action landed — a button depressing under a tap, a checkmark settling into place. Continuity: preserve object permanence — a card should expand into its detail view, not cut to it, so the user's mental model of "where did this come from" survives the transition. Attention: direct the eye to what changed — a new item sliding into a list instead of popping in unannounced.

Anything that isn't doing one of those three jobs is decoration. A parallax layer on scroll that doesn't clarify depth, a logo that spins on launch for no operational reason — that's motion attached to nothing, and "attached to nothing" is precisely what reads as gimmicky. Before adding an animation, name which of the three jobs it's doing. If you can't, cut it.

The duration band nobody deviates from

Material Design's guidance, distilled from years of usability testing, puts most UI transitions between 200 and 300 milliseconds: under 100ms reads as jarring — the eye can't track it as motion at all — and past 500ms it reads as sluggish, like the interface is wading through something. Apple's Human Interface Guidelines don't publish exact numbers but land in the same place philosophically, describing the animations that feel most native as "quick and precise" rather than long and expressive.

Treat that band as a default, not a constant. Scale duration to the distance and area actually moving: a small icon fading in can sit near the bottom of the band, a full-screen transition near the top — but rarely above it. In Flutter, that's the difference between Duration(milliseconds: 150) on an AnimatedOpacity and Duration(milliseconds: 300) on a page-level Hero transition, not a single constant reused everywhere out of habit.

Curves make it feel physical, not robotic

Constant velocity — a linear curve — looks mechanical because nothing in the physical world moves that way; real objects accelerate and decelerate. Material's motion spec names four curves for exactly this: a standard ease-in-out for movement between two onscreen points, a deceleration curve for things entering the screen (fast in, slow to rest), an acceleration curve for things leaving (slow start, fast exit), and a sharp curve for small, quick state changes. Flutter's Curves.easeInOut, Curves.easeOut, and Curves.easeIn map onto the same three cases directly — pick based on whether the thing is entering, leaving, or moving between two visible states, rather than defaulting to whatever the widget ships with.

For anything a finger can interrupt, use a spring

A curve plays out on a fixed timeline from a fixed start to a fixed end. That's fine until a user's finger comes back mid-drag — then the motion needs to redirect from wherever it actually is, at whatever velocity it currently has, which a timeline-based curve can't do and a physics simulation can. That's what a spring is for. SwiftUI's default .spring() uses a response of 0.55 and a damping fraction of 0.825 — response controls how quickly the animation chases its target (lower is snappier), damping fraction controls how much oscillation survives before it settles (1.0 is no bounce at all). Its .interactiveSpring() variant drops response to 0.15 specifically for motion still being tracked under a finger, where any lag between touch and object reads as broken. Flutter has the same physics available through SpringDescription and SpringSimulation — mass, stiffness, and damping instead of response and damping fraction, but the same underlying idea: a real spring, not a lookup table of eased values.

The Flutter-specific gotcha that will burn you

The correct way to respect a user's motion preference is to check MediaQuery.of(context).disableAnimations and fall back to a cross-fade or a hard cut when it's true. The gotcha is that the flag doesn't mean the same thing on every platform it runs on. On Android, toggling "Remove animations" in system accessibility settings flips it reliably. On iOS, Reduce Motion — the setting actually used by people with vestibular disorders and motion sensitivity — has not reliably surfaced through disableAnimations, so code that trusts the flag can end up protecting Android users while doing nothing at all for the iPhone users it was written for. Web support for the matching prefers-reduced-motion media query is newer still. None of this is documented prominently enough that you'll notice by reading the API — it only shows up when you actually flip the OS setting on each platform and watch what your app does, which is worth doing before you ship anything that leans on it.

When to just not animate

Never make an animation the only channel carrying information — a color that pulses once to signal a change, with no static equivalent, is invisible to anyone who missed the pulse or has it turned off. When Reduce Motion is on, don't skip the state change entirely; swap the transition for an instant cross-fade so the outcome is still communicated, just without the travel. And if you're ever unsure whether a proposed animation is feedback, continuity, or attention — it's decoration, and the honest move is to cut it rather than justify it after the fact.

The five-second version: motion needs to be feedback, continuity, or attention, or it's decoration. Keep it in the 200–300ms band, matched to a curve or spring that fits how it's entering, exiting, or being interrupted — and verify Reduce Motion actually reduces motion on every platform you ship to, because Flutter's iOS behavior currently disagrees with what the API name promises.

Where motion actually earns its keep on a listing

Store screenshots are the one surface where none of this applies, because they're static by definition — the whole craft is making a still frame feel alive without a single frame of travel. If a walkthrough of real motion is what would sell your app, that's what an App Store preview video is for, and it's a slot most listings leave completely empty.

Design your screenshots free Where motion belongs: preview videos