UI-Polish
Polish entsteht aus einer Vielzahl kleiner Details, die sich summieren. Dieses Skill ist die Referenz dafür, welche Details es wert sind, umgesetzt zu werden, und welche Werte sie annehmen.
Verlangsame bei der Überprüfung die Oberfläche. Was sich bei 10% Geschwindigkeit falsch anfühlt, ist das, was bei voller Geschwindigkeit subtil falsch ist.
Behalte die Komponentenbibliothek, die Tokens und die Dichte des Projekts bei und stimme die Bewegungssprache ab, außer wenn eine Regel unten eine genaue Interaktion vorschreibt.
Jede Dauer, Kurve und jeder Maßstab und Unschärfe unten sind ein spezifischer Wert, kein Bereich zur Annäherung. cubic-bezier(0.2, 0, 0, 1) ist nicht cubic-bezier(0.4, 0, 0.2, 1), und 0.96 ist nicht 0.95. Verwende, was geschrieben steht.
Textumbruch, Schriftdarstellung, Tabellenzahlen und Textabstand gehören zu better-typography. Trefferflächen, Fokus, Tastaturunterstützung, ARIA und reduzierte Bewegung gehören zu better-accessibility. Gruppierung, Abschnittsabstände, Haltepunkte und räumliches RTL gehören zu better-layout.
Konzentrischer Rahmenradius
Außenradius = Innenradius + Abstand. Nicht übereinstimmende Radien bei verschachtelten Elementen sind das häufigste Element, das eine Oberfläche unstimmig wirken lässt. Rezepte für Radius, Schatten und Umrisse findest du in surfaces.md.
Optische über geometrische Ausrichtung
Wenn die geometrische Zentrierung falsch aussieht, optisch ausrichten. Buttons mit Symbolen, Play-Dreiecke und asymmetrische Symbole erfordern alle einen manuellen Schubser.
Schatten für Erhebung, Rahmen für Struktur
Wo ein Rahmen nur dazu dient, Tiefe zu erzeugen, bevorzuge geschichtete transparente box-shadow-Werte. Behalte Rahmen, die Struktur oder Zustand kommunizieren: Trennlinien, Separatoren und ausgewählte oder Fokus-Zustände.
Unterbrechbare Animationen
Verwende CSS-Übergänge für interaktive Zustandsänderungen, da sie mitten in der Animation unterbrochen werden können. Halte Keyframes für inszenierte Sequenzen vor, die einmal ablaufen.
Eintrittsanimationen aufteilen und staffeln
Für einen seltenen, inszenierten Eintritt, bei dem die Reihenfolge die Hierarchie kommuniziert, teile den Inhalt in semantische Blöcke auf und staffle sie um ~100ms. Ein einzelner Container zu animieren bringt weniger bei gleichem Aufwand. Lasse hochfrequente Interaktionen ungestaffelt. Siehe enter-exit.md.
Subtile Austrittsanimationen
Verwende einen kleinen festen translateY anstelle der vollen Höhe. Austritte sollten weicher sein als Eintritte. Verwende ease-out für beide Richtungen.
Kontextuelle Icon-Animationen
Animiere Icons mit opacity, scale und blur, anstatt die Sichtbarkeit umzuschalten. Verwende genau diese Werte: scale 0.25 bis 1, opacity 0 bis 1, blur 4px bis 0px.
Mit einer Motion-Bibliothek (motion oder framer-motion in package.json), verwende den Import-Pfad dieser Bibliothek oder nahegelegene Importe, falls beide vorhanden sind. Verwende transition: { type: "spring", duration: 0.3, bounce: 0 }. Bounce ist immer 0.
Ohne eine solche Bibliothek: Behalte beide Icons im DOM, wobei eines absolut positioniert ist, und blende sie mit cubic-bezier(0.2, 0, 0, 1) über Kreuz ein/aus. Das ergibt Eintritt und Austritt ohne Abhängigkeit. Beide Rezepte findest du in icon-transitions.md.
Bildumrisse
Gib Bildern eine 1px-Kontur mit geringer Deckkraft für eine konsistente Tiefe. Reines Schwarz im hellen Modus (oklch(0 0 0 / 0.1)), reines Weiß im dunklen (oklch(1 0 0 / 0.1)). Niemals ein beinahe-Schwarz wie Schiefer oder Zink und niemals ein getönter Neutralton. Ein getönter Umriss nimmt die darunterliegende Oberfläche auf und wirkt wie Schmutz am Bildrand.
Skalieren beim Drücken
Ein scale(0.96) beim Klicken gibt einem Button taktiles Feedback. Immer 0.96; alles unter 0.95 wirkt übertrieben. Füge eine static-Eigenschaft hinzu, um es auszuschalten, wo Bewegung ablenken würde. Siehe Rezepte für CSS, Tailwind und Motion.
Animation beim Seitenladen überspringen
Verwende initial={false} bei AnimatePresence, um Eintrittsanimationen beim ersten Rendern zu unterdrücken. Überprüfe, dass beabsichtigte Seiteneintritte intakt bleiben.
Übergänge beim Designwechsel unterdrücken
Ein Designwechsel ändert Farbe, Hintergrund, Rahmen und Schatten auf fast jedem Element gleichzeitig. Jeder Übergang für diese Eigenschaften feuert gleichzeitig und der Wechsel verschmiert anstatt einzurasten. Füge *,*::before,*::after{transition:none !important} ein, erzwinge ein Reflow und entferne es dann im nächsten Frame. Siehe das Rezept.
Nur ändern, was sich ändert
Nenne immer die genauen Eigenschaften: transition-property: scale, opacity. Tailwinds transition-transform deckt transform, translate, scale, rotate ab.
will-change sparsam verwenden
Nur für transform, opacity und filter, die die GPU compositen kann. Niemals will-change: all. Füge es hinzu, wenn du ein Stottern im ersten Frame siehst, nicht vorher. Siehe performance.md.
Icon-Strichstärke an Textgewicht anpassen
Ein Icon neben Text trägt das optische Gewicht des Textes: 1.5px Strich neben normalem (400) Text, 2px neben halbfettem (600). Eine Strichstärke pro Icon-Set und eine Icon-Bibliothek pro Oberfläche. Größenanpassung und RTL-Spiegelung findest du in icons.md.
Ein SVG, pro Zustand neu eingefärbt
Icons verwenden currentColor und nehmen Hover-, Selected- und Disabled-Zustände über CSS-Farbe und -Deckkraft an, niemals über separate Assets. Umriss ist die Standardvariante; Füllung markiert den aktiven Zustand.
Bewegungszurückhaltung
Gib hochfrequenten Interaktionen sofortiges Feedback oder einen Übergang von 150ms oder weniger bei Deckkraft und Farbe. Eine benutzerdefinierte Animation dort kostet bei jedem Auslösen ihre Aufmerksamkeit.
Jede animierte Zustandsänderung benötigt auch einen statischen Hinweis: Farbe, ein Icon oder ein Label. Bewegung ist niemals der einzige Rückmeldungskanal.
Bevor du fertig bist
| Fehler | Korrektur |
|---|---|
| Icons sehen nicht zentriert aus | Optisch mit Padding nachjustieren oder das SVG korrigieren |
| Ruckartiger inszenierter Eintritt oder Austritt | Seltene Eintritte staffeln; Austritte subtil halten |
| Designwechsel überblendet die ganze Seite | Übergänge für den Wechsel deaktivieren, Reflow erzwingen, im nächsten Frame wiederherstellen |
transition: all auf Elementen | Exakte Eigenschaften angeben |
| Animationsstottern im ersten Frame | will-change: transform (sparsam) hinzufügen |
| Haarfeines Icon neben fettem Text | Strichbreite an das Textgewicht anpassen |
Berichterstattung
Schweregrad. HOCH unterbricht eine Interaktion, macht Bewegung unbrauchbar oder hinterlässt eine Zustandsänderung, die nur sichtbar ist, während die Animation läuft. MITTEL ist eine sichtbare Inkonsistenz bei Oberflächen, Symbolen oder Bewegung. NIEDRIG ist eine isolierte Nachbesserung.
Überprüfung. Ohne Browser: jeden Zustand, den die Komponente definiert, also Hover, Fokus, Aktiv, Laden und Leer, sowie Bewegungsdauern und Easings, aus dem Code gelesen. Mit einem: jeden Zustand durchgehen und die Bewegung bei 10% Geschwindigkeit im Animationspanel des Browsers abspielen. Melde jede Überprüfung, die du nicht durchführen konntest, als Nicht überprüft.
Format. Gruppiere die Ergebnisse unter dem jeweils verletzten Prinzip, geordnet nach Schweregrad, eine Zeile pro Ursache, die jeden Ort auflistet, an dem sie auftritt:
| Schweregrad | Ort | Vorher | Nachher | Grund |
|---|
Ort ist Pfad/zur/Datei:Zeile. Grund nennt das Prinzip und die Auswirkung auf den Benutzer.
Beende mit Block, wenn ein HOCH verbleibt, andernfalls mit Genehmigen, und lasse den Rest in der Tabelle als zu erledigende Arbeit stehen. Genehmige niemals eine Abdeckung, die du nicht geprüft hast. Gibt es nichts zu berichten, formuliere „Keine umsetzbaren UI-Polish-Feststellungen“ und melde die Überprüfung.