{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "einblenden-starting-style",
 "name": "Ein-/Ausblenden mit @starting-style",
 "name_en": "Entry/exit animations with @starting-style and allow-discrete",
 "kurz": "Menü, Hovercard und Dialog kommen per @starting-style an und gehen dank allow-discrete sichtbar wieder, ganz ohne Animations-Skript.",
 "kategorie": "Mikroanimationen",
 "kategorie_slug": "mikroanimationen",
 "kategorie_nr": 9,
 "bau_chat": "C4",
 "prioritaet": "A",
 "trendstatus": "aufsteigend",
 "belegstatus": "belegt",
 "website_belege": 4,
 "stimmung": [
  "ruhig",
  "präzise"
 ],
 "stimmung_roh": [
  "ruhig",
  "modern",
  "präzise"
 ],
 "technik": [
  "css",
  "popover-api"
 ],
 "technik_gruppen": [
  "css"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Elemente, die per display, Popover oder Dialog erscheinen, bekommen ihren Startzustand in @starting-style, zum Beispiel opacity 0 und ein kleiner Versatz. Der Browser animiert dann vom Startzustand in den normalen Stil. Mit transition-behavior: allow-discrete laufen auch display und overlay mit. So bleibt das Element beim Schließen sichtbar, bis die Ausblendung fertig ist. Dropdowns, Tooltips, Dialoge und Toasts animieren so ohne JavaScript.",
  "warum_es_wirkt": "Ein Popover, das ankommt statt aufzuploppen, zeigt, woher es kommt und wohin es gehört. Das Auge folgt der Bewegung, der Zustandswechsel wird verständlich. Weil alles in CSS liegt, ist es leicht, schnell und überall gleich.",
  "wann_einsetzen": "Popover, Dialoge, Dropdowns, Tooltips, Hovercards, Toasts, Inline-Meldungen und Elemente mit [hidden]. Auch für Einstiegsanimationen beim ersten Rendern einer Seite.",
  "wann_nicht": "Bei Elementen, die per JavaScript sofort gemessen werden müssen: Während der Startphase haben sie noch Versatz, Scale oder Clip. Nicht für große Seitenübergänge, dafür gibt es View Transitions.",
  "varianten": [
   "Popover oder Dialog mit display und overlay allow-discrete (PostHog: 240 ms, cubic-bezier(.4, 0, .2, 1))",
   "Hovercard: translateY(-10px) scale(.95) auf normal in 0,4 s (Chrome-Leitfaden)",
   "Dialog mit clip-path-Reveal inset(0 0 100%) in 0,4 s, ::backdrop ebenfalls per @starting-style (Cuberto)",
   "Einstieg beim ersten Rendern ohne Auslöser: translateY(8rem) und opacity 0, gestaffelt um 70 bis 100 ms (Collins)"
  ],
  "umsetzung": "[popover] { opacity: 0; translate: 0 -8px; transition: opacity .24s var(--kurve), translate .24s var(--kurve), display .24s allow-discrete, overlay .24s allow-discrete; } [popover]:popover-open { opacity: 1; translate: 0 0; } @starting-style { [popover]:popover-open { opacity: 0; translate: 0 -8px; } }. Der geschlossene Grundzustand ist zugleich das Ziel der Ausblendung. @starting-style muss nach der Open-Regel stehen, sonst gewinnt die Open-Regel bei gleicher Spezifität. Beim Dialog: Lage fest setzen (position: fixed; inset: 0; margin: auto), denn :modal fällt beim Schließen sofort weg und der Dialog würde sonst während der Ausblendung springen. Ein globales margin: 0 löscht das margin: auto des Browsers. Für das ::backdrop gelten dieselben Regeln.",
  "mobil": "Identisch. Hover-Auslöser wie Hovercards auf Touch per Tippen öffnen.",
  "reduzierte_bewegung": "Nur die Deckkraft kurz blenden (etwa 150 ms) oder sofort schalten. Regeln pro Komponente in @media (prefers-reduced-motion: reduce) verschachteln, kein globaler 0.01ms-Trick.",
  "barrierefreiheit": "Popover und Dialog bringen Fokusverwaltung, Escape und Top-Layer mit. Die Animation darf den Fokus nicht verzögern: Er springt sofort, nur die Optik läuft nach. Hovercards zusätzlich per Fokus öffnen und mit Escape schließen."
 },
 "messwerte": {
  "easing": "cubic-bezier(.4,0,.2,1) (PostHog); cubic-bezier(0.215,0.61,0.355,1) (Locomotive)",
  "dauer_ms": "400 (Cuberto); 240 (PostHog); 300 (Locomotive)",
  "stagger_ms": "70–100 (Collins)",
  "distanz": "translateY 8rem (Collins); translateX 100 % (PostHog); clip-path inset 100 % (Cuberto)",
  "sonstiges": "display allow-discrete für <dialog>",
  "herkunft": "beobachtet",
  "quelle": "https://cuberto.com/ ; https://posthog.com/ ; https://www.wearecollins.com/"
 },
 "kurve": {
  "bezier": [
   0.4,
   0.0,
   0.2,
   1.0
  ],
  "css": "cubic-bezier(0.4, 0, 0.2, 1)",
  "name": "Material Standard",
  "dauer_ms": 400
 },
 "gesehen_bei": [
  {
   "seite": "Chrome Developers: Motion",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/motion",
   "auszeichnung": "",
   "beobachtung": "Beispiel .popover-reveal: transition opacity ease-out, display, overlay; 0.2 s; allow-discrete; Reduced-Motion-Regeln pro Regel verschachteln, globales 0.01ms-Hack nicht empfohlen.",
   "art": "artikel"
  },
  {
   "seite": "Chrome Developers: Hovercard",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-components/hovercard",
   "auszeichnung": "",
   "beobachtung": "Konkretes Beispiel mit @starting-style und 0.4 s.",
   "art": "artikel"
  },
  {
   "seite": "Josh W. Comeau: The Big Gotcha With @starting-style",
   "url": "https://www.joshwcomeau.com/css/starting-style/",
   "auszeichnung": "",
   "beobachtung": "Artikel zu Fallstricken von @starting-style (Titel/Zusammenfassung gesehen).",
   "art": "artikel"
  },
  {
   "seite": "Cuberto",
   "url": "https://cuberto.com/",
   "auszeichnung": "",
   "beobachtung": "Showreel-<dialog>: transition opacity .4s, clip-path .4s, display .4s allow-discrete; @starting-style{opacity:0; clip-path:inset(0% 0% 100%)}.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Collins",
   "url": "https://www.wearecollins.com/",
   "auszeichnung": "",
   "beobachtung": "@starting-style{.head__title,.laurels{opacity:0; transform:translateY(8rem)}} – Einstiegsanimation beim Seitenaufbau ohne JS, gestaffelt per transition-delay .07/.1s.",
   "art": "website"
  },
  {
   "seite": "PostHog",
   "url": "https://posthog.com/",
   "auszeichnung": "",
   "beobachtung": ".vac-edge-inspector: --ph-dock-motion 240ms cubic-bezier(.4,0,.2,1); @starting-style{transform:translateX(100%)} für das einfahrende Panel; reduced-motion-Regel vorhanden.",
   "art": "website"
  },
  {
   "seite": "Locomotive",
   "url": "https://locomotive.ca/en",
   "auszeichnung": "",
   "beobachtung": "Formular-Fehlermeldungen: clip-path-Polygon-Reveal .3s cubic-bezier(0.215,0.61,0.355,1) mit @starting-style als Startzustand.",
   "art": "website",
   "browser_gemessen": true
  }
 ],
 "tutorials": [
  {
   "titel": "Chrome: Motion",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/motion"
  },
  {
   "titel": "Chrome: Animate element entry/exit",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/animate-element-entry-exit"
  }
 ],
 "kombinierbar_mit": [
  "hovercard-interest-invoker",
  "toast-stapel",
  "gestaffelte-einblendung",
  "token-federnd-verspielt"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/mikroanimationen/einblenden-starting-style/",
  "meta": "https://cecodesign.de/lab/fundus/mikroanimationen/einblenden-starting-style/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/mikroanimationen/einblenden-starting-style/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: 4 Produktionsbelege."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Menü, Hovercard und Dialog kommen per @starting-style an und gehen dank allow-discrete sichtbar wieder, ganz ohne Animations-Skript.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0.4, 0, 0.2, 1) (Material Standard, PostHog) für alle Varianten",
   "menue": {
    "start": "opacity 0; translate 0 -8px (öffnet es nach oben: +8px, Weg zeigt immer aus dem Anker)",
    "dauer_ms": 240,
    "diskret": "display .24s allow-discrete, overlay .24s allow-discrete",
    "aus": "gleiche Werte wie der Start"
   },
   "hovercard": {
    "start": "opacity 0; translate 0 -10px (oberhalb: +10px); scale .95",
    "dauer_ms": 400,
    "oeffnen_nach_ms": 300,
    "schliessen_nach_ms": 200,
    "transform_origin": "Kante zum Anker"
   },
   "dialog": {
    "start": "opacity 0; clip-path inset(0 0 100% 0)",
    "offen": "opacity 1; clip-path inset(0 0 0 0)",
    "aus": "opacity 0; clip-path inset(100% 0 0 0) (wischt nach unten weg)",
    "dauer_ms": 400,
    "backdrop": "rgb(16 20 43 / 0) → rgb(16 20 43 / .5), 400 ms, ebenfalls @starting-style",
    "lage": "position fixed; inset 0; margin auto; height fit-content"
   },
   "erstauftritt": {
    "start": "opacity 0; translate 0 8rem",
    "dauer_ms": 800,
    "stagger_ms": 70,
    "elemente": 7,
    "ausloeser": "erstes Rendern bzw. Eltern-Element von display none auf sichtbar"
   },
   "reduziert": "nur opacity, 150 ms linear, display/overlay 150 ms allow-discrete; kein translate, scale, clip-path"
  },
  "ausloeser": "klick",
  "touch": "Menü und Dialog per Tippen wie am Desktop. Hovercard öffnet und schließt per Tippen auf den Namen (größere Trefferfläche), Tippen daneben schließt. Hover-Farbwechsel der Knöpfe nur bei (hover: hover).",
  "reduziert": "Alle vier Varianten blenden nur die Deckkraft in 150 ms linear; kein Weg, kein Scale, kein clip-path. Display und overlay laufen weiter diskret mit, damit nichts hart springt.",
  "korrekturen": {
   "beschreibung": "Elemente, die per display, Popover oder Dialog erscheinen, bekommen ihren Startzustand in @starting-style, zum Beispiel opacity 0 und ein kleiner Versatz. Der Browser animiert dann vom Startzustand in den normalen Stil. Mit transition-behavior: allow-discrete laufen auch display und overlay mit. So bleibt das Element beim Schließen sichtbar, bis die Ausblendung fertig ist. Dropdowns, Tooltips, Dialoge und Toasts animieren so ohne JavaScript.",
   "warum_es_wirkt": "Ein Popover, das ankommt statt aufzuploppen, zeigt, woher es kommt und wohin es gehört. Das Auge folgt der Bewegung, der Zustandswechsel wird verständlich. Weil alles in CSS liegt, ist es leicht, schnell und überall gleich.",
   "wann_einsetzen": "Popover, Dialoge, Dropdowns, Tooltips, Hovercards, Toasts, Inline-Meldungen und Elemente mit [hidden]. Auch für Einstiegsanimationen beim ersten Rendern einer Seite.",
   "wann_nicht": "Bei Elementen, die per JavaScript sofort gemessen werden müssen: Während der Startphase haben sie noch Versatz, Scale oder Clip. Nicht für große Seitenübergänge, dafür gibt es View Transitions.",
   "varianten": [
    "Popover oder Dialog mit display und overlay allow-discrete (PostHog: 240 ms, cubic-bezier(.4, 0, .2, 1))",
    "Hovercard: translateY(-10px) scale(.95) auf normal in 0,4 s (Chrome-Leitfaden)",
    "Dialog mit clip-path-Reveal inset(0 0 100%) in 0,4 s, ::backdrop ebenfalls per @starting-style (Cuberto)",
    "Einstieg beim ersten Rendern ohne Auslöser: translateY(8rem) und opacity 0, gestaffelt um 70 bis 100 ms (Collins)"
   ],
   "umsetzung": "[popover] { opacity: 0; translate: 0 -8px; transition: opacity .24s var(--kurve), translate .24s var(--kurve), display .24s allow-discrete, overlay .24s allow-discrete; } [popover]:popover-open { opacity: 1; translate: 0 0; } @starting-style { [popover]:popover-open { opacity: 0; translate: 0 -8px; } }. Der geschlossene Grundzustand ist zugleich das Ziel der Ausblendung. @starting-style muss nach der Open-Regel stehen, sonst gewinnt die Open-Regel bei gleicher Spezifität. Beim Dialog: Lage fest setzen (position: fixed; inset: 0; margin: auto), denn :modal fällt beim Schließen sofort weg und der Dialog würde sonst während der Ausblendung springen. Ein globales margin: 0 löscht das margin: auto des Browsers. Für das ::backdrop gelten dieselben Regeln.",
   "mobil": "Identisch. Hover-Auslöser wie Hovercards auf Touch per Tippen öffnen.",
   "reduzierte_bewegung": "Nur die Deckkraft kurz blenden (etwa 150 ms) oder sofort schalten. Regeln pro Komponente in @media (prefers-reduced-motion: reduce) verschachteln, kein globaler 0.01ms-Trick.",
   "barrierefreiheit": "Popover und Dialog bringen Fokusverwaltung, Escape und Top-Layer mit. Die Animation darf den Fokus nicht verzögern: Er springt sofort, nur die Optik läuft nach. Hovercards zusätzlich per Fokus öffnen und mit Escape schließen."
  },
  "geprueft": "01.11.2026",
  "notiz": "Lektionsseite des erfundenen Online-Kurses „Lernpfad Fotografie“ (Modul 2, Lektion 9: Blende verstehen), gestaltet nach Rezept kurs-coaching-lernweg: kühler heller Grund #eef1f8, Tinte #10142b, Markenton Indigo #3a4bd6, Erfolgsgrün #12a66a für Fortschritt und Haken, Gelb #f6c33b für Sticker und Markierung; Schriften Bricolage Grotesque (opsz 96, wght 700), Onest, Shantell Sans für Modul-Labels, Geist Mono für Bedienung. Übungsbild als eigene SVG-Szene mit Sucher-Raster, Fokusfeld und Belichtungsleiste (offene Blende: Hintergrund per feGaussianBlur weich, Blüte scharf), keine medien/-Bilder. Vier Varianten, alle mit @starting-style und allow-discrete: Menü „Lektionsinhalt“ als natives Popover (popovertarget) mit Kapitelliste, Hovercard der Trainerin als manuelles Popover, modaler Dialog „Übung einreichen“ mit clip-path-Reveal und Backdrop, Erstauftritt der Textspalte beim Laden. Bewegungswerte unverändert gegenüber der Fassung vom 31.10.2026, nur die Backdrop-Farbe folgt der neuen Tinte. JavaScript nur für Lage der Popover (ginge auch mit Anchor Positioning), Hover-Verzögerung und die Vorführung; die Animationen selbst sind reines CSS. Erstauftritt wird wiederholt, indem die Spalte kurz display: none bekommt. Der Vorführ-Zeiger ist selbst ein Popover, damit er über Dialog und Backdrop liegt. Zugang 02.11.2026: Kopfzeile mit flex-wrap (bei 200 % 712 px breit), Fall unter 820 px einspaltig mit minmax(0, 1fr), Kontrastmodus-Rahmen für Knöpfe."
 }
}
