So erstellen Sie Snapping-Scroll-Abschnitte mit CSS Scroll-Snap (fullpage.js-Alternative)

Veröffentlicht: 2022-07-19

In diesem Tutorial erstellen wir eine Seite, die beim Scrollen des Benutzers von einem Vollbildabschnitt zum anderen springt. Dieser Effekt wurde durch die Bibliothek fullpage.js populär gemacht. Aber jetzt gibt es bessere Optionen aufgrund von Lizenzierungsänderungen zu Fullpage (Sie müssen jetzt dafür bezahlen), einem neuen CSS-Scroll-Snap-Modul und vollständiger Browserunterstützung der Schnittmengenbeobachter-API.

Wenn Sie also nach einer Fullpage.js-Alternative suchen, benötigen Sie möglicherweise nicht einmal eine ganze Bibliothek, Sie können sie einfach selbst codieren!

Tatsächlich besteht der Snapping-Effekt zu 100 % aus CSS. JS wird nur verwendet, um Elemente einzublenden, wenn der Bildschirm in die Ansicht "einrastet".

Wir werden diese „Dinosaur Park Scroll Snap Demo“ von Michelle Barker verwenden, die auf CodePen zur Inspiration verfügbar ist:

https://codepen.io/michellebarker/pen/PowYKXJ Sehen Sie sich die Pen Dinosaur Park Scroll Snap Demo von Michelle Barker (@michellebarker) auf CodePen an.

Achtung, Sie möchten dies wahrscheinlich auf einem größeren Bildschirm anzeigen, um den „Scroll Snap“-Effekt vollständig zu erleben.

Durch die Verwendung von CSS in Verbindung mit Intersection Observer sorgen wir dafür, dass jeder Vollbildabschnitt der Seite ein Snap-Scrolling durchführt und den Inhalt einblendet, wenn er in den Darstellungsbereich eintritt.

Noch besser, es sind nur ~30 Zeilen JS-Code! Animationen werden mit CSS erstellt; Alles, was wir tun müssen, ist zu verstehen, wann Abschnitte und Inhalte mit JS in unseren Ansichtsbereich gelangen.

1) Erstellen Sie Ihre Seite

Zunächst müssen Sie eine Seite erstellen oder eine vorhandene konfigurieren, um mit diesem einfachen Effekt kompatibel zu sein. Hier sind zwei Dinge zu beachten:

Wir verwenden ein <main> -Element, das unsere Abschnitte enthält. Dieses Hauptelement ist 100vh, ebenso wie alle <section> -Elemente darin.

HTML:

<main> <section class="section section-1"> <div class="section__content" data-content >Inhalt innerhalb</div> </section> <section class="section section-2"> <div class= "section__content" data-content >Inhalt innerhalb</div> </section> <section class="section section-3"> <header class="section__header"> <h3 class="section__title">Erkunden & Entdecken</h3 > </header> <div class="section__content" data-content >Inhalt innerhalb</div> </section> </main>

CSS:

/* Scroll-Verhalten */ @media (min-height: 30em) { main { scroll-snap-type: y obligatorisch; Höhe: 100vh; Überlauf-y: scrollen; } } .Abschnitt { Farbe: weiß; Position: relativ; scroll-snap-align: center; Anzeige: Flex; Biegerichtung: Säule; Mindesthöhe: 100 Vh; } @media (min-height: 30em) { .section { height: 100vh; } }

2) Fangen mit CSS konfigurieren

Bild-16-11

Hier können wir sehen, dass es mehrere Abschnitte mit jeweils einer Höhe von 100 vh gibt.

Das <main>-Element ist ebenfalls 100vh, mit overflow-y:scroll.

Für den Benutzer ist das Scrollverhalten dasselbe wie bei einer Standardwebseite.

Wenn Sie das oben erwähnte CSS hinzugefügt haben, ist der Snapping-Effekt bereits im Spiel. Werfen wir einen Blick darauf, wie es funktioniert.

Erstens deaktiviert die Abfrage " @media (min-height: 30em) " den Snapping-Effekt für mobile Bildschirme, die in der Höhe zu kurz sind. Unter dem Hauptabschnitt gibt es eine Eigenschaft, die das Einrasten ermöglicht:

main { .... scroll-snap-type: y obligatorisch; .... }

Dies ist eine coole kleine Eigenschaft, die "festlegt, wie streng Snap-Punkte auf dem Scroll-Container erzwungen werden, falls es einen gibt" (MDN).

Und dann haben wir unter unseren Abschnitten:

.section { .... scroll-snap-align: center; .... }

Diese Eigenschaft „gibt die Fangposition der Box als Ausrichtung ihres Fangbereichs (als Ausrichtungssubjekt) innerhalb des Fangports ihres Fangcontainers (als Ausrichtungscontainer) an“ (MDN).

Erfahren Sie hier mehr über das CSS Scroll-Snap-Modul:

Und so einfach ist das. Direkte untergeordnete Elemente innerhalb des <main>-Containers (alle Abschnitte) springen per Scroll-Snap in die Mitte des <main>-Containers. Da sowohl Main als auch Section 100vh sind, springt das Scrollen von Section zu Section.

3) Blenden Sie Inhalte mit Intersection Observer ein

Inzwischen haben wir einen Bildlaufeffekt für die ganze Seite, und wenn Sie nichts weiter tun möchten, können Sie diesen Abschnitt überspringen und Ihre Website genießen. Wenn jedoch jeder ganzseitige Abschnitt sichtbar wird, möchte ich den Inhalt darin einblenden - ein einzigartiger und cooler Effekt (auch einer, der mit fullpage.js möglich ist).

Dazu verwenden wir den Schnittpunktbeobachter, um die Positionierung von Abschnitten in unserem <Haupt>-Ansichtsfenster zu verstehen.

const section = [...document.querySelectorAll("section")]; let options = { rootMargin: "0px", Schwelle: 0,75, }; const callback = (Einträge, Beobachter) => {Einträge.forEach((Eintrag) => {const {Ziel} = Eintrag; if (Eintrag.IntersectionRatio >= 0,75) {Ziel.Klassenliste.Add("is-visible") ; } else { target.classList.remove("is-visible"); } }); }; konstanter Beobachter = neuer IntersectionObserver (Rückruf, Optionen); section.forEach((section, index) => { const sectionChildren = [...section.querySelector("[data-content]").children]; sectionChildren.forEach((el, index) => { el.style .setProperty("--delay", `${index * 250}ms`); }); Observer.observe(Abschnitt); });

Hier werden zwei Dinge getan. Erstens erkennt es, wenn sich ein Abschnitt im Ansichtsfenster befindet, und fügt beim Eintritt eine CSS-Klasse .is-visible hinzu. Beim Verlassen des Ansichtsfensters wird diese Klasse entfernt.

Wenn dieser Abschnitt in das Ansichtsfenster eintritt, legt er außerdem nacheinander (nacheinander) die Verzögerungseigenschaft für 250 ms für jedes der untergeordneten Elemente fest. Dies sorgt für einen gestaffelten Fade-in-Effekt.

Dies geschieht nur bei untergeordneten Elementen innerhalb von Elementen, die das Attribut "Dateninhalt" haben. Sie müssen dies also zu den Wrappern um den Inhalt Ihrer Seiten hinzufügen, wenn Sie den Einblendeffekt wünschen.

Damit dies funktioniert, müssen wir nun die Einblendanimation für Elemente einrichten, denen die Klasse .is-visible hinzugefügt wurde.

@media (Mindesthöhe: 30em) { .section__content > * { Deckkraft: 0; transformieren: translate3d(0, 4rem, 0); Übergang: Deckkraft 800 ms var(--delay), transformiere 800 ms kubische Bezier(0,13, 0,07, 0,26, 0,99) var(--delay); } } .is-visible .section__content > * {Deckkraft: 1; transformieren: translate3d(0, 1rem, 0); } .is-visible .section__img {Deckkraft: 0,75; }

Wenn wir auf den HTML-Code der Anfangsdemo zurückgreifen, werden Sie sehen, dass ein div den Inhalt mit der Klasse .section__content und dem Attribut data-content umschließt.

<main> <section class="section section-1"> <div class="section__content" data-content >Inhalt innerhalb</div> </section> <section class="section section-2"> <div class= "section__content" data-content >Inhalt innerhalb</div> </section> <section class="section section-3"> <header class="section__header"> <h3 class="section__title">Erkunden & Entdecken</h3 > </header> <div class="section__content" data-content >Inhalt innerhalb</div> </section> </main>

Dies verbindet unser JS und CSS miteinander. Die Opazität für Inhalt ist 0, bis die .is-visible Klasse vom Schnittmengenbeobachter hinzugefügt wird, wenn er in das Ansichtsfenster eintritt. Wenn es geht, wird es auf eine Deckkraft von 0 zurückgesetzt, sodass unabhängig von Ihrer Scrollrichtung immer ein Feed wirksam ist.

Schließlich versetzt die delay , die nacheinander auf jedes untergeordnete Element angewendet wird, den Einblendeffekt.

Beachten Sie den dritten Abschnitt. Die Abschnittsüberschrift befindet sich nicht innerhalb eines Abschnitts mit Dateninhalt, sodass er nicht eingeblendet wird (ist bereits vorhanden).

Der ganze Code

Hier ist die Demo:

isotrop-2022-07-15-am-15-00-58

Hier ist der gesamte Code, den wir in unserer Demo verwendet haben:

HTML

<main> <section class="section section-1"> <div class="section__content" data-content> <img class="section__img section__img--left" src="https://s3-us-west-2 .amazonaws.com/s.cdpn.io/85648/trex.svg" alt="T-rex" /> <h2>Inhalt innen</h2> <p>bla bla bla</p> </div> < /section> <section class="section section-2"> <div class="section__content" data-content> <h2>Inhalt innerhalb</h2> <p>bla bla bla</p> </div> </ section> <section class="section section-3"> <header class="section__header"> <h3 class="section__title">Erkunden & Entdecken</h3> </header> <div class="section__content" Dateninhalt > <h2>Inhalt innerhalb</h2> <p>bla bla bla</p> </div> </section> </main>

CSS

@media (min-height: 30em) { main { scroll-snap-type: y obligatorisch; Höhe: 100vh; Überlauf-y: scrollen; } } .Abschnitt { Farbe: weiß; Position: relativ; scroll-snap-align: center; Anzeige: Flex; Biegerichtung: Säule; Mindesthöhe: 100 Vh; } @media (min-height: 30em) { .section { height: 100vh; } } @media (Mindesthöhe: 30em) { .section__content > * { Deckkraft: 0; transformieren: translate3d(0, 4rem, 0); Übergang: Deckkraft 800 ms var(--delay), transformiere 800 ms kubische Bezier(0,13, 0,07, 0,26, 0,99) var(--delay); } } .is-visible .section__content > * {Deckkraft: 1; transformieren: translate3d(0, 1rem, 0); } .is-visible .section__img {Deckkraft: 0,75; }

JS

const section = [...document.querySelectorAll("section")]; let options = { rootMargin: "0px", Schwelle: 0,75, }; const callback = (Einträge, Beobachter) => {Einträge.forEach((Eintrag) => {const {Ziel} = Eintrag; if (Eintrag.IntersectionRatio >= 0,75) {Ziel.Klassenliste.Add("is-visible") ; } else { target.classList.remove("is-visible"); } }); }; konstanter Beobachter = neuer IntersectionObserver (Rückruf, Optionen); section.forEach((section, index) => { const sectionChildren = [...section.querySelector("[data-content]").children]; sectionChildren.forEach((el, index) => { el.style .setProperty("--delay", `${index * 250}ms`); }); Observer.observe(Abschnitt); });

Fazit

Dies ist die perfekte Fullpage.js-Alternative, die nicht nur zwischen den Vollbildabschnitten wechselt. Wir haben auch die Schnittpunktbeobachter-API verwendet, um zu verstehen, wann ein Abschnitt in die Seite eintritt, und dann dynamisch eine gestaffelte Animation anzuwenden. Sie können dieses einfache Beispiel verwenden, um darauf aufzubauen und einige wirklich coole Effekte mit minimalem Vanilla-JS und CSS zu erstellen.