Framer Motion Spring: Presets für Stiffness und Damping

Eine Framer Motion Spring besteht aus zwei Zahlen, die bestimmen, wie sich jeder Tap, jeder Toggle und jedes Popover in deiner App anfühlt. In den meisten Codebases landen Dutzende davon inline: hier stiffness: 400, damping: 17, dort 260 / 20, kopiert aus dem Tutorial, das an dem Tag gerade offen war. Dieses Tutorial ersetzt das durch vier benannte Presets. Es zeigt die echten Werte für Stiffness und Damping aus den Motion Presets von Wingo UI, misst, was jedes Preset tut, und erklärt, welche UI welche Spring bekommt und wie du sie in einer ganzen Komponentenbibliothek teilst.
Das Paket heißt inzwischen motion. Der Upgrade-Guide auf motion.dev (opens in a new tab) (geprüft im Oktober 2026) ersetzt framer-motion durch motion und verschiebt die Imports nach motion/react. Die Spring-Optionen bleiben gleich: Eine Framer Motion Spring und eine motion react spring transition nehmen dieselben Werte stiffness, damping und mass. Alles hier nutzt motion 12.43.
Wie funktioniert eine Framer Motion Spring Animation?
Eine Spring hat keine feste Dauer. Motion simuliert eine Masse an einer Feder: stiffness bestimmt, wie stark die Feder zum Ziel zieht, damping ist die Reibung, die sie bremst, und mass gibt an, wie schwer das bewegte Objekt ist (standardmäßig 1). Die Animation endet, sobald der Wert nah genug am Ziel und langsam genug ist, um anzuhalten.
Für die UI-Arbeit hat das zwei wichtige Folgen:
- Das Gefühl entsteht aus dem Verhältnis, nicht aus den rohen Zahlen. Das Dämpfungsverhältnis ist
damping / (2 * Math.sqrt(stiffness * mass)). Unter 1 schießt der Wert über das Ziel hinaus und schwingt zurück. Ab 1 kommt er ohne Überschwingen an. Zwei Springs mit demselben Verhältnis wirken wie dieselbe Kurve in unterschiedlichem Tempo. - Eine Spring behält ihre Geschwindigkeit, wenn du das Ziel änderst. Laut der Transition-Doku von Motion (opens in a new tab) übernehmen physikalische Springs die Geschwindigkeit laufender Gesten oder Animationen, zeitbasierte nicht. Tippst du zweimal schnell auf ein Segmented Control, biegt der Thumb zur neuen Option ab, statt anzuhalten und neu zu starten.
Das Verhältnis prüfst du in einer Zeile:
Welche Werte für Stiffness und Damping sollte eine UI nutzen?
Wenn du nur Werte zum Kopieren suchst: Diese vier aus lib/motion.ts in Wingo UI sind die einzigen Springs, die unsere Komponenten nutzen.
Wir haben jedes Preset mit dem spring()-Generator von motion selbst gemessen, aus motion-dom 12.43: ein Wert, der von 0 auf 100 animiert, mit Masse 1. „Innerhalb 1 %“ ist die Zeit, ab der der Wert nur noch höchstens eine Einheit vom Ziel abweicht.
Lies die Tabelle aus Sicht der Nutzer, und denk daran: Die Einschwingzeit ist nicht die gefühlte Geschwindigkeit. Snappy legt 90 % der Strecke in 120 ms zurück, smooth braucht dafür 188 ms. Den Rest seiner Zeit verbringt snappy mit 4 % Überschwingen, und genau das fühlt sich an, als reagiere das Control direkt auf den Finger. Smooth kommt insgesamt etwas früher zur Ruhe, ohne sichtbares Überschwingen, also wackelt ein Dialog beim Öffnen nie. Bouncy schießt um ein Fünftel über: Auf einem Erfolgshaken macht das einmal Spaß, auf jedem Popover nervt es. Gentle braucht etwa eine halbe Sekunde und bleibt ruhig, das passt zu einem ganzen Chart, das sich aufbaut.
Die letzte Zeile ist die Falle. Schreibst du transition={{ type: "spring" }} ohne Zahlen, fällt motion auf Stiffness 100 und Damping 10 zurück: fast eine Sekunde Einschwingen und 16 % Überschwingen. Gib immer ein benanntes Preset an.
Die Demo unten ist gleichzeitig ein Framer Motion Spring Visualizer: Vier Bälle laufen nebeneinander mit den vier Springs. Wähl in den Playground-Controls eine Spring und spiel dann die Liste erneut ab, um sie an echten Zeilen zu sehen.
$ npx wingo-ui@latest add motionWie sieht jedes Spring Preset in echten Komponenten aus?
Snappy für alles, was ein Finger berührt
Alle drückbaren Flächen der Bibliothek teilen sich denselben Press-Effekt: Skalierung auf 0,97 mit springs.snappy. Der kostenlose Button holt ihn aus einer einzigen Konstante, und deine eigenen Komponenten können das auch:
Der kostenlose Switch bewegt seinen Thumb mit animate(pos, checked ? 1 : 0, springs.snappy) auf einem Motion Value und dehnt den Thumb mit derselben Spring, solange er gedrückt bleibt. Das kostenlose Segmented Control schiebt seinen Thumb ebenfalls mit snappy und gibt dessen aktuelle Geschwindigkeit an die nächste Animation weiter. Ein zweiter Tap mitten in der Bewegung ändert die Richtung also ohne Ruck:
$ npx wingo-ui@latest add segmented-controlDer Guide zum React Segmented Control (auf Englisch) behandelt den Rest dieses Controls, vom ziehbaren Thumb bis zur Radio-Semantik.
Smooth als Standard für Overlays und Layout
Dialoge, Toasts, Listenzeilen und Inhaltswechsel erscheinen alle mit springs.smooth. Mit ihrem Verhältnis von 0,87 schwingt smooth 0,4 % über. Bei einem Dialog, der 8px nach oben an seinen Platz gleitet, sind das ein paar Hundertstel Pixel, also landet die Fläche weich und ohne sichtbares Wackeln. Popovers und Menüs sind die Ausnahme: Ihr Preset nutzt snappy, weil sie direkt auf einen Klick antworten. Smooth ist auch die richtige Spring für layout-Animationen, bei denen ein Bounce benachbarte Inhalte zittern ließe.
Achte auf den Exit: ein kurzes Tween, keine Spring. Ein schneller Abgang wirkt reaktionsschnell, und der Auftritt darf sich Zeit lassen. Deshalb verschwinden die meisten Presets in lib/motion in 150 ms.
Bouncy für einen Akzent pro Screen
Bouncy gehört dorthin, wo ein kleiner Jubelmoment gewollt ist: Die Icon-Kachel eines Alert Dialogs poppt mit { ...springs.bouncy, delay: 0.06 } auf, und ein Erfolgshaken kann das genauso. Lass es weg bei allem, was Leute viele Male am Tag öffnen. Die 20 % Überschwingen, die beim ersten Mal Freude machen, sind beim zehnten Menü nur noch Rauschen.
Gentle für große Flächen
Große Elemente sollten sich langsam bewegen. Chart-Balken wachsen mit springs.gentle und einer kleinen Verzögerung pro Balken, und Seitenabschnitte blenden damit ein. Bei Stiffness 120 dauert die Bewegung etwa eine halbe Sekunde und schießt nie sichtbar über. Ein 300px hoher Balken schießt also nicht über seinen Wert hinaus und zeigt nicht für einen Moment falsche Daten.
Wie teilst du Springs in einer Komponentenbibliothek?
Leg sie in eine Datei und importier sie überall. Mit drei Gewohnheiten bleibt diese Datei die einzige Quelle für Spring-Werte:
- Benannte Presets, nie Inline-Zahlen. In Wingo UI tauchen
springs.snappyundsprings.smoothjeweils in mehr als 100 Komponentendateien auf (Stand Oktober 2026). Etwa 15 Komponentendateien stimmen für eine bestimmte Geste noch eine Spring inline ab. Das sind die Ausnahmen, die einen Review wert sind, nicht die Regel. Das Gefühl der ganzen Bibliothek neu abzustimmen ist eine Änderung in einer Zeile. - Presets über den Springs. Ein Preset bündelt
initial,animate,exitundtransition. Ein Popover ist also<motion.div {...presets.popover} />statt vier Props, die mit der Zeit auseinanderlaufen. - Ein einziger Weg für reduzierte Bewegung.
useMotionTransition(springs.smooth)gibt die Spring zurück oder{ duration: 0 }, wenn jemand reduzierte Bewegung eingestellt hat, unduseMotionPreset("popover")macht aus Bewegung einen kurzen Opacity-Fade. Beide lesen die Einstellung erst nach der Hydration, damit Server- und Client-Markup übereinstimmen. Unser Guide zu prefers-reduced-motion erklärt, warum das in Next.js wichtig ist.
Wenn dir ein Provider lieber ist: MotionConfig von motion nimmt eine transition entgegen, die für jede Motion-Komponente darin zum Standard wird. <MotionConfig transition={springs.smooth}> an der Wurzel ersetzt also die eingebauten Defaults von motion in deiner App. Zwei Einschränkungen: Dieser Standard gilt auch für Opacity und Farben, die dann das 0,3-Sekunden-Tween von motion verlieren. Und reduzierte Bewegung ist eine eigene Einstellung: reducedMotion="user" auf demselben MotionConfig schaltet Transform-Animationen ab, wenn das System es verlangt. Komponenten, die snappy brauchen, geben es weiterhin explizit an.
Die ganze Datei bekommst du mit npx wingo-ui@latest add motion. Sie ist kostenlos und installiert das Paket motion sowie den SSR-sicheren Media-Query-Hook, den sie für reduzierte Bewegung nutzt.
Können CSS Transitions dieselbe Spring nutzen?
Ja, für alles, was nicht über motion läuft, etwa ein Tailwind-Hover oder ein Wechsel von data-state. CSS linear() nimmt eine Liste von Punkten und zeichnet die Kurve durch sie hindurch. Du kannst eine Spring also einmal abtasten und als Easing verwenden. MDN führt linear() als Baseline, seit Dezember 2023 in allen Browsern verfügbar.
Wingo UI liefert zwei abgetastete Gegenstücke als Tokens in globals.css: --motion-ease-snappy mit --motion-duration-snappy (450 ms) für snappy und --motion-ease-spring mit --motion-duration-spring (500 ms) für smooth. Das Überschwingen siehst du in den Zahlen: Die snappy-Kurve erreicht ihren Höchstwert bei 1,0398, also die 4 % aus der Tabelle oben.
Eine abgetastete Kurve kann ihre Geschwindigkeit nicht behalten, wenn sie unterbrochen wird. Nutz sie für einfache Zustandswechsel und lass Drags, Thumbs und alles, was oft ein neues Ziel bekommt, bei den Springs von motion.
Welche Fehler lassen Springs falsch wirken?
- Springs ohne Namen. Jedes Inline-
stiffnessist eine künftige Inkonsistenz. Durchsuch deine Codebase nachstiffness:außerhalb der Preset-Datei. - Bouncy auf Elementen, die Leute den ganzen Tag öffnen. Heb dir das Überschwingen für Momente auf, die es verdienen.
- Bouncy Springs auf Opacity und Farben. Opacity endet bei 1, also ist ein Überschwingen von 20 % unsichtbar und verzögert nur das Ende der Animation. Ein reiner Fade wirkt als kurzes Tween besser, und das ist auch der Default von motion für Werte ohne Transform. Läuft Opacity zusammen mit einem Transform auf smooth, wie in den Presets oben, sind 0,4 % Überschwingen zu wenig, um eine Rolle zu spielen.
- Duration und Physik in einem Objekt. Laut der Motion-Doku werden
bounceunddurationüberschrieben, sobaldstiffness,dampingodermassgesetzt sind.{ duration: 0.2, stiffness: 400 }ignoriert die Dauer also stillschweigend. - Kein Weg für reduzierte Bewegung. Bewegung, die die Systemeinstellung ignoriert, kann bei manchen Menschen Übelkeit auslösen. Leite jede Spring durch einen einzigen Hook.
Weitere Guides wie diesen findest du unter Komponenten-Guides. Oder fang mit dem Pillar an, unserem Guide zu React Formular-Komponenten, der diese Springs in jedem Feld nutzt.
Was solltest du als Nächstes installieren?
Fang mit den Presets an: npx wingo-ui@latest add motion kopiert lib/motion.ts kostenlos in dein Projekt, mit den vier Springs, den Presets, den Gesten-Schwellenwerten und den Hooks für reduzierte Bewegung. Ergänz danach den kostenlosen Button, Switch oder das Segmented Control, und sie übernehmen automatisch dieselben Springs.
Häufige Fragen
Welche Werte für Stiffness und Damping eignen sich für eine Framer Motion Spring?
Für UI deckt eine Stiffness zwischen 120 und 500 mit einem Dämpfungsverhältnis von etwa 0,7 bis 0,9 fast alles ab; geh nur für einen bewussten Bounce tiefer. Unsere vier Presets sind 500 / 32 für Press-Feedback und Toggles, 300 / 30 für Overlays und Layout, 400 / 18 für verspielte Akzente und 120 / 20 für große Flächen, alle mit der Standardmasse 1.
Welche Spring nutzt Framer Motion standardmäßig?
In motion 12.43 animiert ein Transform wie x oder y mit Stiffness 500 und Damping 25, scale mit Stiffness 550 und Damping 30 (kritisch gedämpft, wenn der Wert Richtung 0 geht), und Opacity oder Farben bekommen ein Tween von 0,3 Sekunden. Gibst du type: "spring" ohne Zahlen an, gelten die Physik-Defaults Stiffness 100, Damping 10 und Masse 1, und die schwingen etwa 16 % über.
Sollte ich duration und bounce oder stiffness und damping verwenden?
Nimm duration und bounce, wenn dir das Design eine Zeit vorgibt, und stiffness und damping, wenn die Spring die Geschwindigkeit einer Geste oder einer unterbrochenen Animation behalten soll. Laut der Motion-Doku übernehmen physikalische Springs diese Geschwindigkeit, zeitbasierte nicht, und stiffness, damping oder mass überschreiben duration und bounce.
Wie verhindere ich, dass eine Framer Motion Spring nachfedert?
Erhöhe damping, bis das Dämpfungsverhältnis 1 erreicht, also damping mindestens 2 * sqrt(stiffness * mass). Bei Stiffness 300 und Masse 1 sind das etwa 35; alles darüber kommt ohne Überschwingen an, nur langsamer.
Ist Framer Motion dasselbe wie das Paket motion?
Ja. Framer Motion erscheint jetzt als motion, und der Upgrade-Guide auf motion.dev ersetzt npm install framer-motion durch npm install motion und importiert aus motion/react. Spring-Optionen wie stiffness, damping und mass funktionieren genauso.
- Motion
- Animation
- React
- Design Systems


