{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "gestaffelte-einblendung",
 "name": "Gestaffelte Einblendung per sibling-index()",
 "name_en": "Staggered entrance with sibling-index()",
 "kurz": "Nach dem Filterwechsel kommen die Projektkarten eines Zürcher Architekturbüros nacheinander, der Verzug kommt rein aus CSS über sibling-index().",
 "kategorie": "Mikroanimationen",
 "kategorie_slug": "mikroanimationen",
 "kategorie_nr": 9,
 "bau_chat": "C4",
 "prioritaet": "B",
 "trendstatus": "aufsteigend",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "ruhig",
  "laut"
 ],
 "stimmung_roh": [
  "rhythmisch",
  "ruhig"
 ],
 "technik": [
  "css"
 ],
 "technik_gruppen": [
  "css"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Elemente einer Liste oder eines Rasters erscheinen nacheinander statt gleichzeitig. Das geht ohne JavaScript: animation-delay: calc(sibling-index() * var(--stagger)). sibling-index() liefert die Position unter den Geschwistern, sibling-count() ihre Anzahl. Beide sind seit 18.08.2026 Baseline (Chrome und Edge ab 138, Safari ab 26.2, Firefox ab 154). Ein Skript, das --i setzt, braucht es nur noch als Rückfall für ältere Browser.",
  "warum_es_wirkt": "Die Staffelung gibt Rhythmus und führt das Auge in Lesereihenfolge. Inhalte wirken choreografiert statt aufgeploppt.",
  "wann_einsetzen": "Menüeinträge, Karten nach einem Filterwechsel, Suchergebnisse, Dropdown-Einträge, Toasts.",
  "wann_nicht": "Bei langen Listen: höchstens 6 bis 8 Elemente staffeln, den Rest gleichzeitig zeigen. Bei UI-Elementen, die man oft öffnet: dort nervt die Wartezeit.",
  "varianten": [
   "Linear nach Index: calc((sibling-index() - 1) * var(--stagger))",
   "Aus der Mitte: Abstand zur Mitte als Verzug, |sibling-index() - (sibling-count() + 1) / 2|, mit max() statt abs() geschrieben",
   "Umgekehrt beim Schließen: calc((sibling-count() - sibling-index()) * var(--stagger))",
   "Mit Obergrenze: min(sibling-index() - 1, 5), damit die Gesamtdauer begrenzt bleibt"
  ],
  "umsetzung": ".liste > * { --stagger: 150ms; animation: einrutschen 700ms cubic-bezier(0.1, 0.9, 0.3, 1) both, einblenden 900ms cubic-bezier(0.1, 0.9, 0.3, 1) both; animation-delay: calc(var(--i, 0) * var(--stagger)); animation-delay: calc((sibling-index() - 1) * var(--stagger)); } @keyframes einrutschen { from { translate: 0 8px } } @keyframes einblenden { from { opacity: 0 } } @media (prefers-reduced-motion: reduce) { .liste > * { animation: einblenden 150ms linear both; animation-delay: 0s } }. Die erste animation-delay-Zeile ist der Fallback (JS setzt --i), Browser ohne sibling-index() verwerfen die zweite. Damit die Animation bei einem Filterwechsel neu startet und nur die Treffer zählen, die Elemente neu einsetzen statt sie mit hidden zu verstecken: sibling-index() zählt auch versteckte Geschwister. Browserstand (Web Features Explorer, 02.11.2026): sibling-index() und sibling-count() sind Baseline Newly available seit 18.08.2026. Die @supports-Weiche mit JS-Rückfall bleibt sinnvoll, bis die Funktionen Widely available sind (etwa Anfang 2029); wer nur aktuelle Browser bedient, kann den Rückfall weglassen, dann erscheinen ältere Browser ohne Staffel, aber vollständig.",
  "mobil": "Identisch. Bei zwei Spalten folgt der Verzug der Lesereihenfolge.",
  "reduzierte_bewegung": "Kein Verzug und keine Bewegung, höchstens ein kurzes gemeinsames Einblenden (150 ms).",
  "barrierefreiheit": "Die Inhalte stehen sofort im DOM und sind fokussierbar, sie sind nur optisch verzögert. Filterknöpfe mit aria-pressed, die neue Trefferzahl über eine aria-live-Region ansagen."
 },
 "messwerte": {
  "easing": "Standard",
  "dauer_ms": "700 (Slide) / 900 (Fade)",
  "stagger_ms": "150",
  "distanz": "translateY 8 px",
  "sonstiges": "@supports-Weiche sibling-index() mit nth-child-Fallback",
  "herkunft": "beobachtet",
  "quelle": "https://www.apple.com/v/iphone/home/cl/built/styles/overview.built.css"
 },
 "kurve": null,
 "gesehen_bei": [
  {
   "seite": "Chrome Developers: Dynamic sibling animations",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/dynamic-sibling-animations",
   "auszeichnung": "",
   "beobachtung": "--stagger-time 0.1s, animation fade-in 0.4s, animation-delay: calc(sibling-index() * var(--stagger-time)); Reduced Motion: animation none; JS-Fallback setzt --sibling-index.",
   "art": "artikel"
  },
  {
   "seite": "Apple – iPhone",
   "url": "https://www.apple.com/iphone/",
   "auszeichnung": "",
   "beobachtung": "Chapternav: --r-chapternav-item-index: calc(sibling-index() - 1) in @supports, Fallback nth-child(0–11); animation-delay = 0.15s × Index; slidein 700 ms (8 px) + fadein 900 ms.",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Chrome: Dynamic sibling animations",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/dynamic-sibling-animations"
  }
 ],
 "kombinierbar_mit": [
  "einblenden-starting-style",
  "toast-stapel",
  "skeleton-shimmer"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/mikroanimationen/gestaffelte-einblendung/",
  "meta": "https://cecodesign.de/lab/fundus/mikroanimationen/gestaffelte-einblendung/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/mikroanimationen/gestaffelte-einblendung/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: Produktionsbeleg für sibling-index() bei Apple."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Nach dem Filterwechsel kommen die Projektkarten eines Zürcher Architekturbüros nacheinander, der Verzug kommt rein aus CSS über sibling-index().",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "stagger_ms": 150,
   "verzug": "calc((sibling-index() - 1) * 150ms)",
   "verzug_mitte": "calc(max(sibling-index() - (sibling-count() + 1) / 2, (sibling-count() + 1) / 2 - sibling-index()) * 150ms)",
   "verzug_gedeckelt": "calc(min(sibling-index() - 1, 5) * 150ms)",
   "einrutschen": "translate 0 8px → 0, 700 ms",
   "einblenden": "opacity 0 → 1, 900 ms",
   "easing_ein": "cubic-bezier(0.1, 0.9, 0.3, 1)",
   "ausblenden": "opacity → 0, translate 0 8px, 250 ms, cubic-bezier(0.1, 0.6, 0.4, 1)",
   "verzug_aus": "calc(min(sibling-count() - sibling-index(), 5) * 30ms), also rückwärts",
   "ui_ms": 250,
   "fallback": "JS setzt --i (Index ab 0) und --n (Anzahl) am Element; Deklaration mit var() zuerst, native mit sibling-index() danach; Weiche @supports (animation-delay: calc(sibling-index() * 1ms))",
   "neustart": "Karten werden beim Filterwechsel neu ins DOM gesetzt (replaceChildren), dadurch startet die Animation neu und sibling-index() zählt nur die Treffer",
   "reduziert": "opacity 150 ms linear, kein Verzug, kein Weg"
  },
  "ausloeser": "klick",
  "touch": "Wie am Desktop: Tippen auf einen Filter blendet die Treffer gestaffelt ein. Raster zweispaltig, Lesereihenfolge links nach rechts, oben nach unten. Kein Hover-Zoom auf den Modellbildern.",
  "reduziert": "Kein Verzug und kein Rutschen: alle Karten blenden gleichzeitig in 150 ms ein, das Ausblenden entfällt. Die Werte-Anzeige meldet „kein Verzug“.",
  "korrekturen": {
   "beschreibung": "Elemente einer Liste oder eines Rasters erscheinen nacheinander statt gleichzeitig. Das geht ohne JavaScript: animation-delay: calc(sibling-index() * var(--stagger)). sibling-index() liefert die Position unter den Geschwistern, sibling-count() ihre Anzahl. Beide sind seit 18.08.2026 Baseline (Chrome und Edge ab 138, Safari ab 26.2, Firefox ab 154). Ein Skript, das --i setzt, braucht es nur noch als Rückfall für ältere Browser.",
   "warum_es_wirkt": "Die Staffelung gibt Rhythmus und führt das Auge in Lesereihenfolge. Inhalte wirken choreografiert statt aufgeploppt.",
   "wann_einsetzen": "Menüeinträge, Karten nach einem Filterwechsel, Suchergebnisse, Dropdown-Einträge, Toasts.",
   "wann_nicht": "Bei langen Listen: höchstens 6 bis 8 Elemente staffeln, den Rest gleichzeitig zeigen. Bei UI-Elementen, die man oft öffnet: dort nervt die Wartezeit.",
   "varianten": [
    "Linear nach Index: calc((sibling-index() - 1) * var(--stagger))",
    "Aus der Mitte: Abstand zur Mitte als Verzug, |sibling-index() - (sibling-count() + 1) / 2|, mit max() statt abs() geschrieben",
    "Umgekehrt beim Schließen: calc((sibling-count() - sibling-index()) * var(--stagger))",
    "Mit Obergrenze: min(sibling-index() - 1, 5), damit die Gesamtdauer begrenzt bleibt"
   ],
   "umsetzung": ".liste > * { --stagger: 150ms; animation: einrutschen 700ms cubic-bezier(0.1, 0.9, 0.3, 1) both, einblenden 900ms cubic-bezier(0.1, 0.9, 0.3, 1) both; animation-delay: calc(var(--i, 0) * var(--stagger)); animation-delay: calc((sibling-index() - 1) * var(--stagger)); } @keyframes einrutschen { from { translate: 0 8px } } @keyframes einblenden { from { opacity: 0 } } @media (prefers-reduced-motion: reduce) { .liste > * { animation: einblenden 150ms linear both; animation-delay: 0s } }. Die erste animation-delay-Zeile ist der Fallback (JS setzt --i), Browser ohne sibling-index() verwerfen die zweite. Damit die Animation bei einem Filterwechsel neu startet und nur die Treffer zählen, die Elemente neu einsetzen statt sie mit hidden zu verstecken: sibling-index() zählt auch versteckte Geschwister. Browserstand (Web Features Explorer, 02.11.2026): sibling-index() und sibling-count() sind Baseline Newly available seit 18.08.2026. Die @supports-Weiche mit JS-Rückfall bleibt sinnvoll, bis die Funktionen Widely available sind (etwa Anfang 2029); wer nur aktuelle Browser bedient, kann den Rückfall weglassen, dann erscheinen ältere Browser ohne Staffel, aber vollständig.",
   "mobil": "Identisch. Bei zwei Spalten folgt der Verzug der Lesereihenfolge.",
   "reduzierte_bewegung": "Kein Verzug und keine Bewegung, höchstens ein kurzes gemeinsames Einblenden (150 ms).",
   "barrierefreiheit": "Die Inhalte stehen sofort im DOM und sind fokussierbar, sie sind nur optisch verzögert. Filterknöpfe mit aria-pressed, die neue Trefferzahl über eine aria-live-Region ansagen."
  },
  "geprueft": "01.11.2026",
  "notiz": "Welt aus Rezept architektur-ruhiges-raster: erfundenes Büro „Hollenstein Marti Architekten“, Zürich, Werkverzeichnis mit Typologie-Filtern (Pill-Filter nach dem Prinzip von Archiv-Navigationen). Hanken Grotesk in einem Schnitt, achromatisch, Fokus #0022FF. Die Bilder sind eigene isometrische Modellfotos als SVG (Karton, Balsa, Beton, Bestand in Grau), per JS erzeugt. Jede Karte zeigt ihren tatsächlich berechneten Verzug (aus getComputedStyle gelesen). Umschalter Linear / Aus der Mitte / Gedeckelt; Ausblenden immer rückwärts. Werte von Apple (Chapternav: 150 ms, 700 ms Rutschen um 8 px, 900 ms Einblenden), Kurve aus dem Rezept. Vorführung: ein gedachter Zeiger klickt Filter, die Variante wechselt mit. AD-Review 01.11.2026: Note 5 Zugang 02.11.2026: Projekt-Links mit aria-label (Titel, Ort Jahr, Stand), weil Chromium den Namen aus figure/figcaption im Link nicht bildet; --meta #76767a → #6e6e72 (5,1:1); Werte-Labels (dt) in --meta statt --tertiaer (1,7:1); Kontrastmodus-Rahmen für Knöpfe. Hinweis: Kontrasttreffer an späten Karten sind Messartefakte, die Prüfung misst bei 1,5 s, die Staffel (10 × 150 ms + 900 ms) läuft bis 2,25 s. Korrektur 02.11.2026: Status sibling-index()/sibling-count() Baseline seit 18.08.2026 (Web Features Explorer: Chrome/Edge 138, Safari 26.2, Firefox 154; web.dev Baseline-Digest August 2026) in beschreibung und umsetzung. Demo unverändert, Quelle-Anzeige nennt nativ oder JS-Rückfall."
 }
}
