Apple Design
Wie Apple Oberflächen baut, die sich nicht mehr wie ein Computer anfühlen, sondern wie eine Erweiterung Ihrer selbst. Dieses Wissen stammt aus Apples WWDC-Design-Vorträgen – hauptsächlich Designing Fluid Interfaces (WWDC 2018) – destilliert und für die Web-Plattform übersetzt (CSS, Pointer Events, requestAnimationFrame, Federbibliotheken wie Motion/Framer Motion).
Der rote Faden: Eine Oberfläche fühlt sich lebendig an, wenn die Bewegung vom aktuellen Bildschirmwert ausgeht, die Geschwindigkeit des Benutzers übernimmt, Momentum projiziert und in jedem Moment gegriffen und umgekehrt werden kann. Federn sind das Werkzeug, das all dies natürlich macht, da sie von Natur aus unterbrechbar und geschwindigkeitsbewusst sind.
Die Kernidee
„Wenn wir die Oberfläche an die Art und Weise anpassen, wie wir denken und uns bewegen, geschieht etwas Magisches – es fühlt sich nicht mehr wie ein Computer an, sondern wie eine nahtlose Erweiterung unserer selbst.“
Eine Oberfläche ist fließend, wenn sie sich wie die physische Welt verhält: Dinge reagieren sofort, bewegen sich kontinuierlich, tragen Momentum, widerstehen an Grenzen und können während der Bewegung umgelenkt werden. Alles, was folgt, ist ein Weg, dem näher zu kommen.
Apple stellt Design als Dienst an vier menschlichen Bedürfnissen dar: Sicherheit/Vorhersagbarkeit, Verständnis, Leistung und Freude. Jede Regel hier dient einem davon.
1. Reaktion – Latenz töten
Sobald eine Verzögerung auftritt, fällt das Gefühl der Direktheit „von einer Klippe.“ Reaktion ist das Fundament, auf dem alles andere aufbaut.
- Reagieren Sie beim Zeiger-nach-unten, nicht beim Loslassen. Heben Sie einen Knopf hervor, sobald er gedrückt wird. Auf
click/Touch-Ende zu warten, um Feedback zu zeigen, fühlt sich tot an. - Seien Sie wachsam bei jeder Latenz. Überprüfen Sie Entprellungen, künstliche Timer, Übergangsverzögerungen und die ~300 ms Tap-Verzögerung. Alles auf dem Eingabepfad, das nicht wesentlich ist, ist ein Rückschritt.
- Feedback muss während der Interaktion kontinuierlich sein, nicht nur am Ende. Ziehen Sie für einen Drag, einen Schieberegler oder eine Schublade die UI 1:1 mit dem Zeiger den ganzen Weg mit – animieren Sie niemals nur, wenn die Geste abgeschlossen ist.
/* Feedback lebt auf dem Druck, und es ist sofort */
.button:active {
transform: scale(0.97);
transition: transform 100ms ease-out;
}
2. Direkte Manipulation – 1:1-Verfolgung
„Berührung und Inhalt sollten sich zusammen bewegen.“
Wenn der Benutzer etwas zieht, muss es am Finger kleben bleiben – und den Versatz von der Stelle respektieren, an der es gegriffen wurde. Auf die Mitte des Elements beim Greifen zu schnappen, zerstört die Illusion sofort.
- Verwenden Sie Pointer Events mit
setPointerCapture, damit die Verfolgung auch dann fortgesetzt wird, wenn der Zeiger die Elementgrenzen verlässt. - Verfolgen Sie eine kurze Geschwindigkeits-/Positionshistorie (die letzten paar
pointermove-Ereignisse), nicht nur den aktuellen Punkt – Sie werden die Geschwindigkeit beim Loslassen benötigen.
el.addEventListener('pointerdown', (e) => {
el.setPointerCapture(e.pointerId);
const grabOffset = e.clientY - el.getBoundingClientRect().top; // respektieren, wo sie gegriffen haben
// ...Positions- + Zeitstempelhistorie für Geschwindigkeit verfolgen
});
3. Unterbrechbarkeit – das wichtigste Prinzip überhaupt
„Der Gedanke und die Geste geschehen parallel.“
Jede Animation muss unterbrechbar und jederzeit umlenkbar sein. Ein Benutzer muss ein sich bewegendes Element im Flug greifen und umkehren können, ohne darauf warten zu müssen, dass die Animation endet. Ein schließendes Modal, das der Benutzer erneut greift, sollte dem Finger folgen – nicht zuerst fertig schließen und dann wieder öffnen.
- Sperren Sie die Eingabe während eines Übergangs niemals aus.
- Animieren Sie immer vom Darstellungs (aktuellen) Wert, niemals vom Zielwert. Beim Unterbrechen lesen Sie die Live-Bildschirm-Transformation des Elements und starten die neue Animation von dort. Vom logischen/Zielwert zu beginnen, verursacht einen sichtbaren Sprung.
- Vermeiden Sie CSS-Übergänge und
@keyframesfür alles gestengesteuerte – sie können nicht sanft gegriffen und im Flug umgekehrt werden. Federn animieren standardmäßig vom aktuellen Wert, was genau das ist, was eine Unterbrechung braucht. - Wenn eine Geste umkehrt, mischen Sie die Geschwindigkeit – schneiden Sie sie nicht hart ab. Das Ersetzen einer Animation durch eine andere bei einer Umkehrung erzeugt eine Geschwindigkeitsdiskontinuität, eine „Betonmauer.“ Federbibliotheken, die die Geschwindigkeit durch ein erneutes Zielen tragen, vermeiden dies. (Das tun iOS' additive Animationen nativ; wählen Sie im Web eine Federbibliothek, die mit der aktuellen Geschwindigkeit neu zielt.)
- Zerlegen Sie 2D-Bewegungen in unabhängige X- und Y-Federn. Eine einzelne Feder auf einer 2D-Distanz desynchronisiert, wenn X und Y unterschiedliche Geschwindigkeiten haben.
4. Verhalten über Animation – Federn verwenden
„Denken Sie an Animation als ein Gespräch zwischen Ihnen und dem Objekt, nicht als etwas, das von der Oberfläche vorgeschrieben wird.“
Eine vorab festgelegte Animation mit fester Dauer kann nicht auf neue Eingaben reagieren. Eine Feder kann – neue Eingaben ändern einfach das Ziel, und die Bewegung bleibt kontinuierlich. Greifen Sie zu Federn für alles, was ein Benutzer berühren kann.
Apple hat absichtlich das Physik-Triplett (Masse/Steifigkeit/Dämpfung) durch zwei designerfreundliche Parameter ersetzt. Denken Sie in diesen:
- Dämpfungsverhältnis – steuert das Überschwingen.
1.0= kritisch gedämpft, kein Nachschwingen, sanftes Einpendeln.< 1.0= überschwingt und oszilliert. Niedriger = schwungvoller. - Ansprechzeit – wie schnell der Wert das Ziel erreicht, in Sekunden. Niedriger = schneller. Dies ist keine „Dauer“ – eine Feder hat keine feste Dauer; ihre Einschwingzeit ergibt sich aus den Parametern.
Standardeinstellungen:
- Starten Sie die meisten UIs mit Dämpfung
1.0(kritisch gedämpft) – anmutig und nicht ablenkend. - Fügen Sie Nachschwingen (Dämpfung ~
0.8) nur hinzu, wenn die Geste selbst Momentum trug (ein Wischen, ein Werfen, ein Loslassen nach einem Zug). Überschwingen bei einem Menü, das gerade eingeblendet wurde, fühlt sich falsch an; Überschwingen bei einer Karte, die Sie gewischt haben, fühlt sich richtig an.
Konkrete Werte, die Apple ausliefert:
| Interaktion | Dämpfung | Ansprechzeit |
|---|---|---|
| Bewegen / Neupositionieren (z. B. PiP) | 1.0 | 0.4 |
| Drehung | 0.8 | 0.4 |
| Schublade / Sheet | 0.8 | 0.3 |
Web-Mapping (Motion / Framer Motion): Die bounce + duration Feder-API ist Apples Dämpfung + Ansprechzeit sehr ähnlich. Ein sicherer Hausstil ist standardmäßig damping: 1.0 Federn überall; reservieren Sie Nachschwingen für momentumgetriebene, physische Interaktionen.
import { animate } from 'motion';
// Kritisch gedämpfter Standard (kein Überschwingen)
animate(el, { y: 0 }, { type: 'spring', bounce: 0, duration: 0.4 });
// Momentum-Interaktion – ein wenig Nachschwingen, nur weil ein Wischen vorausging
animate(el, { y: target }, { type: 'spring', bounce: 0.2, duration: 0.4 });
5. Geschwindigkeitsübergabe – die Naht zwischen Ziehen und Animation
Wenn eine Geste endet, muss die Animation mit der exakten Geschwindigkeit des Fingers fortgesetzt werden, damit keine sichtbare Naht zwischen Ziehen und Animieren entsteht. Dies ist das Detail, das „fließend“ am meisten von „in Ordnung“ unterscheidet.
Übergeben Sie die Loslassgeschwindigkeit des Zeigers als Anfangsgeschwindigkeit der Feder. Einige Feder-APIs benötigen eine relative Geschwindigkeit – normalisieren Sie sie durch die verbleibende Distanz zum Ziel:
relativeVelocität = GestenGeschwindigkeit / (ZielWert − AktuellerWert)
Beispiel: Element bei y=50, Ziel y=150 (100px zu gehen), Finger bewegt sich mit 50px/s → Anfangsgeschwindigkeit der Feder = 50 / 100 = 0.5. Framer Motion / Motion nimmt die absolute Geschwindigkeit in px/s direkt (velocity-Option), daher übergeben Sie normalerweise den Rohwert.
6. Momentum-Projektion – animieren Sie dorthin, wo die Geste hingeht
„Nehmen Sie eine kleine Eingabe und machen Sie eine große Ausgabe.“
Schnappen Sie nicht zur nächsten Grenze vom Loslasspunkt aus. Verwenden Sie die Geschwindigkeit, um die Ruheposition zu projizieren – genau wie bei der Bildlaufverzögerung – und schnappen Sie dann zum Ziel, das diesem projizierten Punkt am nächsten liegt. Das ist es, was ein Wischen das Gefühl gibt, das Element zu werfen.
Apples genaue Projektionsfunktion (aus dem Beispielcode von Designing Fluid Interfaces):
// decelerationRate ≈ 0.998 für normales Bildlaufgefühl; 0.99 für schnelleres
function project(initialVelocity /* px/s */, decelerationRate = 0.998) {
return (initialVelocity / 1000) * decelerationRate / (1 - decelerationRate);
}
const projectedEndpoint = currentPosition + project(releaseVelocity);
const target = nearestSnapPoint(projectedEndpoint); // Ziel aus der Projektion wählen
animateSpringTo(target, { velocity: releaseVelocity }); // dann Geschwindigkeit übergeben (§5)
Hinweis: Die Physik-Lehrbuchformel v²/(2·decel) ist nicht das, was Apple ausliefert – verwenden Sie die obige exponentielle Abklingform. Dies ist das Standardverhalten in guten Bottom-Sheets und Karussells (Vaul, Embla).
7. Räumliche Konsistenz – symmetrische Pfade, verankerte Ursprünge
„Wenn etwas auf eine Weise verschwindet, erwarten wir, dass es dort auftaucht, wo es herkam.“
- Betreten und verlassen Sie auf demselben Pfad. Ein Panel, das von rechts hereingleitet, muss nach rechts verschwinden. Hereinkommen von rechts / Hinausgehen unten wirkt zusammenhangslos und verwirrend.
- Verankern Sie Interaktionen an ihrer Quelle. Ein Menü, Popover oder Sheet sollte von dem Element ausgehen, das es ausgelöst hat – setzen Sie
transform-originauf den Auslöser, damit die räumliche Beziehung zwischen Schaltfläche und Inhalt offensichtlich ist. (Dies ist derselbe Punkt der Ursprungsbewusstheit wie bei Popovern, die von ihrem Auslöser skalieren, nicht von ihrer Mitte.) - Spiegeln Sie die Beschleunigung bei umkehrbaren Übergängen, sodass der Abgangspfad mit dem Rückkehrpfad übereinstimmt (verwenden Sie inverse kubische Bézier-Kontrollpunkte für die beiden Richtungen).
8. Hinweis in der Richtung der Geste
Menschen sagen einen Endzustand aus einer Flugbahn voraus. Zwischenbewegungen sollten vorhersagen, wohin die Dinge gehen – Control Center-Module „wachsen nach oben und außen zu Ihrem Finger hin.“ Lassen Sie die Zwischenbilder auf das Ergebnis zeigen, nicht nur blind darauf interpolieren.
9. Gummiband-Effekt – weiche Grenzen
An einer Grenze widerstehen Sie progressiv, anstatt hart zu stoppen. Ein harter Stopp wirkt wie „eingefroren“; kontinuierlicher Widerstand wirkt wie „reagiert, aber es gibt nichts mehr hier.“ Wenden Sie eine Dämpfung an, die zunimmt, je weiter der Benutzer über die Grenze hinaus zieht.
// Je weiter über die Grenze, desto weniger folgt das Element – echte Dinge werden langsamer, bevor sie stoppen
function rubberband(overshoot, dimension, constant = 0.55) {
return (overshoot * dimension * constant) / (dimension + constant * Math.abs(overshoot));
}
10. Details des Gestendesigns (die „Gefühls“-Checkliste)
- Tippen: Hervorheben bei Berührung-unten (sofort), ausführen bei Berührung-oben. Fügen Sie ~10px Hysterese/Hit-Padding um das Ziel hinzu, und erlauben Sie das Abbrechen durch Wegziehen und Zurückkommen.
- Ziehen/Wischen: Erfordern Sie eine kleine Bewegungsschwelle (Hysterese, ~10px), bevor Sie sich für eine Richtung entscheiden, dann verfolgen Sie 1:1.
- Erkennen Sie alle plausiblen Gesten parallel ab der ersten Bewegung, brechen Sie dann die Verlierer selbstbewusst ab, sobald die Absicht klar ist. Vermeiden Sie Erkennungsmodule, die nur einen endgültigen Zustand melden (
swipeleft-artige Ereignisse) – sie verwerfen die kontinuierliche Verfolgung, die Sie für das Feedback benötigen. - Minimieren Sie Verzögerungen bei der Disambiguierung. Die Doppeltipp-Erkennung verzögert zwangsläufig einzelne Tipps; zahlen Sie diese Kosten nur dort, wo Doppeltipp tatsächlich existiert.
11. Bildgenaue Glätte
Glätte betrifft das, was in den Bildern ist, nicht nur die Bildwiederholrate.
- Halten Sie die positionsbezogene Änderung pro Bild unter der Wahrnehmungsschwelle, um Stroboskopeffekte zu vermeiden.
- Bei sehr schnellen Bewegungen codiert eine subtile Bewegungsunschärfe / Dehnung die Geschwindigkeit und wirkt besser als ein harter, scharfer Strich.
requestAnimationFrameist die anzeigensynchronisierte Uhr des Webs (Apple verwendetCADisplayLink). Animieren Sie nur kompositorfreundliche Eigenschaften –transformundopacity– und geben Sie mitwill-changeeinen Hinweis, wo Bewegung unmittelbar bevorsteht.
12. Materialien & Tiefe – Transluzenz vermittelt Hierarchie
Apple verwendet transluzente Materialien als schwebende funktionale Schicht, die Struktur bringt, ohne die Aufmerksamkeit zu stehlen. Annäherung im Web mit backdrop-filter.
- Bauen Sie Navigations-/Symbolleisten/Sheets als transluzente Schichten (
backdrop-filter: blur()+ ein halbtransparenter Hintergrund) mit darunter scrollendem Inhalt – und nicht als undurchsichtige Balken, die einen festen Streifen verbrauchen. - Materialgewicht codiert Hierarchie: dunklere/schwerere Materialien trennen strukturelle Regionen (Seitenleisten); hellere Materialien lenken die Aufmerksamkeit auf interaktive Elemente (Schaltflächen). Stapeln Sie niemals eine helle transluzente Oberfläche auf eine andere – die Lesbarkeit bricht zusammen.
- Größere Oberflächen sollten als dicker wahrgenommen werden: stärkere Unschärfe + ein tieferer Schatten als bei kleinen Chips. Betrachten Sie kontextbewusste Schatten – schwerer über belebten/Textinhalten für Trennung, leichter über einfachen Hintergründen.
- Abdunkeln zum Fokussieren, trennen, um den Fluss zu erhalten. Eine modale Aufgabe paart die Oberfläche mit einem abdunkelnden Scrim und schiebt den Hintergrund zurück/nach unten. Ein paralleles, nicht blockierendes Panel verwendet Transluzenz und Versatz ohne einen Scrim, damit der Fluss nicht unterbrochen wird. Bei gestapelten Sheets verdunkeln und schieben Sie jede übergeordnete Ebene progressiv zurück.
- Vibranz hält Text über wechselnden Hintergründen lesbar. Verwenden Sie über unscharfen/transluzenten Oberflächen kein flaches graues Text – verwenden Sie kontrastreichere, etwas schwerere Schriftstärke und eine kleine Erhöhung der Zeichenabstände. Setzen Sie Farbe auf eine feste Schicht, nicht auf den transluzenten Vordergrund.
- Bildlauf-Randefekte, keine harten Trennlinien. Verblassen Sie anstelle einer 1px-Grenze unter einem klebrigen Header eine kleine Unschärfe-/Verlaufsmaske, wo Inhalt auf schwebendes Chrom trifft – nur dort, wo schwebende UI tatsächlich Inhalt überlappt.
- Materialisieren Sie, verblassen Sie nicht nur. Animieren Sie bei Glas-/Unschärfeoberflächen den Unschärferadius und die Skalierung zusammen beim Ein-/Ausgang, sodass die Oberfläche als ein echtes ankommendes Material gelesen wird und nicht als eine einfache Deckkraft-Blende.
.toolbar {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px) saturate(180%);
border-top: 1px solid rgba(255, 255, 255, 0.4); /* helle Oberkante = Licht, das auf das Material trifft */
}
13. Multimodales Feedback – Bewegung + Ton + Haptik
Drei Regeln für die Kombination von Sinnen (aus Designing Audio-Haptic Experiences):
- Kausalität – es muss offensichtlich sein, was das Feedback verursacht hat. Lösen Sie es beim tatsächlichen kausalen Ereignis aus (das Umlegen des Schalters, das Einrasten des Objekts) und passen Sie seinen Charakter an die Physis der Aktion an.
- Harmonie – das Visuelle, der Ton und die Haptik müssen im selben Bild ausgelöst werden. Latenz zwischen ihnen zerstört die Illusion. Lassen Sie nicht zu, dass ein CSS-Übergang die Audio-/Haptik-API (Vibration API) verzögert.
- Nützlichkeit – fügen Sie Feedback nur dort hinzu, wo es seinen Platz verdient. Reservieren Sie Haptik/Ton für bedeutungsvolle Momente (Erfolg, Fehler, Bestätigung, Einrasten). Übermäßiges Feedback bringt Benutzern bei, alles zu ignorieren.
14. Reduzierte Bewegung & Barrierefreiheit
Reduzierte Bewegung bedeutet nicht kein Feedback