{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "elastisches-raster-lag",
 "name": "Elastisches Raster (Spalten mit Scroll-Verzögerung)",
 "name_en": "Elastic grid scroll / column lag",
 "kurz": "Ein Bildarchiv in Spalten, die beim Scrollen verschieden lange nachziehen: außen träger, innen schneller. Beim Stoppen holen sie weich auf.",
 "kategorie": "Hero & Section-Layouts",
 "kategorie_slug": "hero-layouts",
 "kategorie_nr": 4,
 "bau_chat": "C2",
 "prioritaet": "C",
 "trendstatus": "aufsteigend",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "ruhig",
  "luxuriös"
 ],
 "stimmung_roh": [
  "weich",
  "hochwertig",
  "ruhig"
 ],
 "technik": [
  "gsap",
  "scrollsmoother",
  "css-grid",
  "lenis"
 ],
 "technik_gruppen": [
  "css",
  "gsap",
  "lenis"
 ],
 "leistungskosten": "mittel",
 "steckbrief": {
  "beschreibung": "Ein mehrspaltiges Bildraster (Projekte, Fotos) wird in Spalten-Wrapper gruppiert. Beim Scrollen folgt jede Spalte mit eigener Verzögerung (Lag): die mittleren Spalten reagieren schneller, die äußeren hängen nach. Hört der Scroll auf, holen die Spalten weich auf. So wirkt das Raster elastisch und schwer. Variante: Die Spalten laufen gegenläufig, abwechselnd hoch und runter.",
  "warum_es_wirkt": "Eine einfache Galerie bekommt Gewicht und wirkt hochwertig, weil die Spalten sich wie Körper mit Masse verhalten. Das Layout selbst bleibt unverändert, der Effekt liegt nur in der Bewegung.",
  "wann_einsetzen": "Projektraster, Fotogalerien und Archivseiten mit Smooth Scrolling.",
  "wann_nicht": "Ohne Smooth-Scroll-Setup, auf Seiten mit viel Text und wenn die Leistung knapp ist.",
  "varianten": [
   "Lag nach Abstand zur Mitte",
   "Gegenläufige Spalten",
   "Lag nur beim Einscrollen der Sektion"
  ],
  "umsetzung": "GSAP ScrollSmoother mit smooth: 1, effects: true und normalizeScroll: true. Die Spaltenzahl aus getComputedStyle(grid).gridTemplateColumns lesen und die Kacheln in .grid__column-Wrapper verteilen, damit weniger Elemente animiert werden. Pro Spalte smoother.effects(col, { speed: 1, lag }) mit lag = baseLag + |i − mid| × lagScale und mid = (n − 1) / 2. Bei Resize neu aufbauen. Ohne ScrollSmoother: Lenis plus eigene Lerp pro Spalte, wie in dieser Demo.",
  "mobil": "Lag stark verkürzen oder abschalten, sonst fühlt sich der Touch-Scroll schwammig an.",
  "reduzierte_bewegung": "Kein Lag, normales Scrollen.",
  "barrierefreiheit": "Durch die Verteilung in Spalten liest ein Screenreader spaltenweise statt zeilenweise. Ist die Reihenfolge wichtig, die Originalreihenfolge im DOM behalten und nur visuell verteilen."
 },
 "messwerte": {
  "easing": "",
  "dauer_ms": "",
  "stagger_ms": "",
  "distanz": "data-speed -0.04 bis 0.06 je Kachel",
  "sonstiges": "Codrops-Artikel nennt ScrollSmoother; auf der Live-Seite eigene data-speed-Attribute",
  "herkunft": "beobachtet",
  "quelle": "https://www.yzavoku.com/projects"
 },
 "kurve": null,
 "gesehen_bei": [
  {
   "seite": "YZA Voku – Projects",
   "url": "https://tympanus.net/codrops/2025/06/03/elastic-grid-scroll-creating-lag-based-layout-animations-with-gsap-scrollsmoother/",
   "auszeichnung": "YZA Voku: Awwwards SOTD 14.01.2025 + Developer Award",
   "beobachtung": "Laut Codrops wird yzavoku.com/projects als Beispiel für diesen Effekt zitiert.",
   "art": "artikel",
   "weitere_beobachtung": "Spaltenanzahl aus grid-template-columns gelesen, Items in Spalten-Wrapper verteilt, Lag pro Spalte nach Distanz zur Mitte."
  },
  {
   "seite": "YZA Voku – Projects",
   "url": "https://www.yzavoku.com/projects",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (HTML): jede Projektkachel trägt eigene Scroll-Geschwindigkeit data-speed (-0.04, 0.01, 0.06 …) mit data-speed-mod – Spalten laufen versetzt.",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Elastic Grid Scroll (Codrops)",
   "url": "https://tympanus.net/codrops/2025/06/03/elastic-grid-scroll-creating-lag-based-layout-animations-with-gsap-scrollsmoother/"
  },
  {
   "titel": "ElasticGridScroll (GitHub)",
   "url": "https://github.com/codrops/ElasticGridScroll"
  }
 ],
 "kombinierbar_mit": [
  "broken-grid-asymmetrisch",
  "horizontal-scroll-section",
  "layout-formation-scroll"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hero-layouts/elastisches-raster-lag/",
  "meta": "https://cecodesign.de/lab/fundus/hero-layouts/elastisches-raster-lag/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hero-layouts/elastisches-raster-lag/demo"
 },
 "herkunft": {
  "quelldateien": [
   "layouts.json",
   "patch-belege-3.json"
  ],
  "pruefnotizen": [
   "patch-belege-3.json: Erster Produktionsbeleg; bleibt C."
  ],
  "kategorie_alt": "Projektlisten"
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein Bildarchiv in Spalten, die beim Scrollen verschieden lange nachziehen: außen träger, innen schneller. Beim Stoppen holen sie weich auf.",
  "demo": true,
  "abhaengigkeiten": [
   "lenis@1.3.26"
  ],
  "werte": {
   "lag_formel": "lag = 0,2 s + |i − Mitte| × 0,3 s, Mitte = (n − 1) / 2",
   "lag_4_spalten_s": "0,65 · 0,35 · 0,35 · 0,65",
   "lag_3_spalten_s": "0,5 · 0,2 · 0,5",
   "lag_2_spalten_s": "0,35 · 0,35",
   "nachziehen": "je Frame y += (scrollY − y) × (1 − e^(−dt / (lag × 1000 / 4))), also rund 98 % aufgeholt nach lag Sekunden; Versatz = scrollY − y",
   "versatz_max_px": 260,
   "gegenlaeufig": "zusätzlich ±10 % des Abstands zwischen Viewport-Mitte und Rastermitte, Spalten abwechselnd; lag einheitlich 0,25 s",
   "nur_einscrollen": "Versatz × Gewicht, Gewicht = (Rasteroberkante − 5 % vh) / 55 % vh, begrenzt auf 0 bis 1",
   "smooth_scroll": "Lenis lerp 0.1, smoothWheel true, syncTouch false, autoRaf false (raf im selben Frame wie die Spalten)",
   "touch_faktor": 0.35,
   "spalten": "4 ab 1101 px, 3 bis 1100 px, 2 bis 640 px; Anzahl aus getComputedStyle(raster).gridTemplateColumns, Neuaufbau bei Resize (150 ms entprellt)",
   "versatz_gerade_spalten": "padding-top clamp(40px, 9vh, 110px)",
   "bild_einblenden": "opacity 600 ms cubic-bezier(0.455, 0.03, 0.515, 0.955) (easeInOutQuad, Rezept), Platzhalter #e6e6e6 in aspect-ratio",
   "hover_titel": "opacity 350 ms cubic-bezier(0.455, 0.03, 0.515, 0.955)",
   "vorfuehrung": "5 Scroll-Stöße zu je min(55 % vh, 420 px) in 700 ms easeInOutQuad, 950 ms Pause, Rückfahrt 1400 ms; Varianten wechseln je Runde",
   "farben": "#f4f4f2 Grund, #141414 Text, #e6e6e6 Platzhalter, #8a8a8a Bildunterschrift und Zähler",
   "schriften": "Instrument Serif 400 (Name, Titel), Instrument Sans (Text 14–15 px), Fragment Mono 12 px tabular-nums (Zähler, Bildunterschrift)"
  },
  "ausloeser": "scroll",
  "touch": "Zwei Spalten. Lenis glättet Touch nicht (syncTouch: false), die Seite scrollt nativ. Das Nachziehen ist auf 35 % verkürzt (lag 0,12 s je Spalte), damit sich der Daumen-Scroll nicht schwammig anfühlt. Kein Hover-Titel, der Ort steht in der Bildunterschrift; der Zähler sitzt unten links.",
  "reduziert": "Lenis startet nicht, die Spalten bekommen keinen Versatz, die Seite scrollt normal. Bilder blenden nur in 200 ms linear ein. Die Vorführung springt von Stoß zu Stoß statt zu gleiten.",
  "korrekturen": {
   "beschreibung": "Ein mehrspaltiges Bildraster (Projekte, Fotos) wird in Spalten-Wrapper gruppiert. Beim Scrollen folgt jede Spalte mit eigener Verzögerung (Lag): die mittleren Spalten reagieren schneller, die äußeren hängen nach. Hört der Scroll auf, holen die Spalten weich auf. So wirkt das Raster elastisch und schwer. Variante: Die Spalten laufen gegenläufig, abwechselnd hoch und runter.",
   "warum_es_wirkt": "Eine einfache Galerie bekommt Gewicht und wirkt hochwertig, weil die Spalten sich wie Körper mit Masse verhalten. Das Layout selbst bleibt unverändert, der Effekt liegt nur in der Bewegung.",
   "wann_einsetzen": "Projektraster, Fotogalerien und Archivseiten mit Smooth Scrolling.",
   "wann_nicht": "Ohne Smooth-Scroll-Setup, auf Seiten mit viel Text und wenn die Leistung knapp ist.",
   "varianten": [
    "Lag nach Abstand zur Mitte",
    "Gegenläufige Spalten",
    "Lag nur beim Einscrollen der Sektion"
   ],
   "umsetzung": "GSAP ScrollSmoother mit smooth: 1, effects: true und normalizeScroll: true. Die Spaltenzahl aus getComputedStyle(grid).gridTemplateColumns lesen und die Kacheln in .grid__column-Wrapper verteilen, damit weniger Elemente animiert werden. Pro Spalte smoother.effects(col, { speed: 1, lag }) mit lag = baseLag + |i − mid| × lagScale und mid = (n − 1) / 2. Bei Resize neu aufbauen. Ohne ScrollSmoother: Lenis plus eigene Lerp pro Spalte, wie in dieser Demo.",
   "mobil": "Lag stark verkürzen oder abschalten, sonst fühlt sich der Touch-Scroll schwammig an.",
   "reduzierte_bewegung": "Kein Lag, normales Scrollen.",
   "barrierefreiheit": "Durch die Verteilung in Spalten liest ein Screenreader spaltenweise statt zeilenweise. Ist die Reihenfolge wichtig, die Originalreihenfolge im DOM behalten und nur visuell verteilen."
  },
  "geprueft": "01.11.2026",
  "notiz": "Welt: Rezept fotograf-film-bild-zuerst, erfundene Fotografin Noemi Thommen aus Basel, Archivseite mit 24 Serien vom Rhein (Bilder als eigene Canvas-Szenen, kein Foto aus medien/). Die Demo nutzt die Alternative ohne ScrollSmoother: Lenis plus Lerp pro Spalte. Umschalter für drei Varianten, Pult zeigt Lag je Spalte und den Live-Versatz in px. Das Werk wird nie im Ausschnitt verschoben, nur die Spalte als Ganzes (Rezeptregel). Referenzen: tympanus.net, yzavoku.com, readcereal.com, timwalkerphotography.com. AD-Review 01.11.2026: Note 4. Pult startet eingeklappt (data-fundus-pult=\"zu\"), weil es beim Scrollen sonst Bildunterschriften und am Ende die Fußzeile verdeckt. Zugang 02.11.2026: --leise #8a8a8a → #6e6e6e (4,6:1); Kopf und Fuß position relative, z-index 2 über den nachlaufenden Spalten (Fokus auf Marke und Footer-Link nicht verdeckt); Kontrastmodus-Rahmen für Knöpfe."
 }
}
