Onepager mit Parallax-Scrolleffekt

Für Desktop und mobile Browser - auch iOS / iPadOS Safari

Eine gerne genutzte Layoutvariante für kleine Websites mit relativ wenig Textinhalten sind Onepager mit großen Bildblöcken und mehr oder minder stark ausgeprägtem Parallax-Effekt. Wir haben der Vorteil einer vollflächig gestalteten Benutzeroberfläche und können zudem die Botschaft in Form einer fortschreitenden Geschichte mit starker Bildsprache erzählen. Hierbei sind also die großflächigen Bilder und ihre Zusammenstellung das wichtigste Gestaltungselement.

Hinzu kommt eine Art spielerische Komponente, da sich erst durch die Parallaxe bzw. die mit dem Scrollen der Seite wandernden Bildausschnitte neue Aspekte eines Bildes ausprägen, die das Motiv statisch gar nicht hergeben würde. Zudem bleibt das Gesamtlayout in der Höhe kompakter, da technisch gesehen die überstrichenen Bilder zwar alle vollflächig den Viewport ausfüllen, aber immer nur ein weniger hoher Ausschnit davon zu sehen sein muss.

Der Witz liegt also tatsächlich in der Animation und quasi interaktiven Komposition.

Die Recherche und Auswahl der Bildmotive ist für Parallax deutlich anspruchsvoller, da die Bilder bei unterschiedlichsten Ausschnitten noch prägnanten Inhalt zeigen müssen. Dabei kommen meist entweder sehr abstrakte Motive zum Einsatz, oder solche, deren wichtigste Aspekte ziemlich exakt in der Bildmitte liegen.

Schade nur, dass (Stand 2022/06) der ganze Effekt für mobile Endgeräte mit den meisten herkömmlichen CSS Layoutmethoden nicht wirklich funktioniert. Entweder zeigt sich dort das Layout relativ ruckelig und unruhig beim Scrollen der Seite (Android: Chrome, Firefox). Oder die vereinfachte CSS Variante funktioniert schlicht überhaupt nicht. So im SamsungInternet und vor allen Dingen im mobile Apple Safari, da dieser Browser background-attachment:fixed immer noch nicht unterstützt.

Mit anderen Worten: für eine nicht unrelevante Zielgruppe ist der Witz des Parallax-Layouts überhaupt nicht erfahrbar und die Seite stellt sich spürbar "simpler" dar, als für die Desktopversion angedacht. Zudem stimmt ggf. die ursprünglich konzipierte Erzählung im Zusammenspiel von Fotos und Texten nicht mehr, da das statische Layout zum Beispiel andere Flächenverhältnisse aufweist.

So oder so muss man für mobile Endgeräte eine weitere Layoutvariante im Auge behalten, die auch ohne Parallax-Scrolleffekt eine starke Wirkung erzielt. Und das bedeutet Mehrarbeit durch zusätzliche @media queries und komplexere CSS Regeln.

Schade also um die viele Arbeit? Nope!

Die hier gezeigte Lösung funktioniert nicht nur auf den relevanten mobilen Endgeräten, sondern hat im Gegensatz zur vereinfachten CSS Variante auch noch eine Sekundäranimation, um einen "echten" Parallax-Effekt beim Scrollen der Seite zu simulieren.

Die Grundidee ist, das beim Safari fehlende background-attachment:fixed auf andere Weise mit CSS zur emulieren. Das geht und ist schon in der Grundausführung auf allen mobilen Browser praktisch ruckelfrei einsetzbar. Es bleiben zwar typischerweise ein paar Sprünge übrig, da praktisch alle mobilen Browser beim Herunterscrollen der Seite die Kopfleiste ausblenden und sich dadurch die Höhe des Viewports sprunghaft ändert. Aber im Großen und Ganzen scrollt das Layout schon ziemlich geschmeidig mit dem Dokument.

Für einen "echten" Parallax-Effekt muss aber noch eine Sekundäranimation hinzugefügt werden, so dass sich das Bild im Ausschnitt der wandernden Maske langsamer bewegt, als die quasi im Vordergrund laufenden Seiteninhalte. Die unterschiedlichen Scrollgeschwindigkeiten simulieren eine Art Raumtiefe, wie wir sie aus der Beobachtung der realen Welt kennen.

Das in der Demo gezeigte Seitenlayout ist voll responsive und verarbeitet auch nebeneinander gestellte Parallax-Container, Text/Bild Kombinationen sowie zwischengeschaltete reine Textblöcke. Es ist sogar möglich, die Technik mit einem angepassten Wordpress Blocklayout Theme zu nutzen. Die Sekundäranimation ist zwar weitgehend flüssig. Aber es kommt je nach Browser und Endgerät immer wieder zu sporadischen Sprüngen bzw. im Firefox auch zu kontinuierlichem leichten Zittern der Hintergrundbilder.

In einer idealen Welt - CSS 3D perspective

Im Zuge der Entwicklung habe ich einige der gängigen dokumentierten Methoden zur Umsetzung von Parallax Layouts durchprobiert. Ohne die Sekundäranimation ist der Effekt ziemlich schwach und eigentlich auch nicht wirklich ein Parallax Effekt.

Die "perfekte" Lösung ist, die native Parallaxe aus dem Einsatz von CSS 3D Staffelung über perspective() und translateZ() zu nutzen. Der 3D Raum wird von allen Browser super geschmeidig gerendert und zeigt überhaupt keinen jitter beim Scrollen des documents. Sogar der Firefox rendert die Seitenelemente auf einem älteren Android Smartphone super smooth.

Dies mag daran liegen, dass der gesamte Zeichenprozess bei 3D intern vom Browser selbst mit dem Update des viewports beim Scrollen synchronisiert wird.

Das ist der entscheidende Punkt, der bei allen anderen durchprobierten Lösungen, die irgendwie mit Hilfe von Javascript und Scroll-Events bzw. requestAnimationFrame()  arbeiten, zu einem mehr oder minder starken Zittern oder Springen der Seitenelemente beim Scrollen führt.

Wir liegen selbst bei hoher Wiederholfrequenz niemals im selben Zyklus wie das Neuzeichnen des Browsers. Dadurch werden die statischen Seitenelemente bereits in Scrollrichtung neu gezeichnet, während wir mit der Animation der eigenen Parallaxe um einige Zehntel hinterher hinken. Die Stärke des jitter ist dabei je nach Endgerät und Browser unterschiedlich.

Ideal wäre also, für die Parallaxe das native CSS 3D zu nutzen. Leider gibt es aber wie immer einen Wermutsropfen. Innerhalb der durch perspective() gesteuerten 3D DOM Hierarchie darf auf keinem Element overflow:hidden oder clip-path gesetzt werden. Das bricht die Perspektive und führt zu einem fallback auf transform-style:flat.

Außerdem sind die mit translateZ() perspektivisch gestaffelten Elemente nicht mehr frei positionierbar. Und auch die Größenkompensation mittels transform:scale() ist einigermaßen tricky, wenn man zwar die Parallaxe nutzen will, die Elemente aber in Originalgröße zurück skalieren will.

Mit anderen Worten: so lange alle Seitenelemente quasi "frei" in der Seite unbeschnitten schweben dürfen, ist das gesamte Layout ziemlich einfach umzusetzen. Das ist dann eher eine Frage des Designs als der Funktion. Der von mir angestrebte Effekt, dass die vollflächigen Bildstreifen quasi von einem "wandernden" Ausschnit überstrichen werden, lässt sich aber auch in 3D nicht befriedigend umsetzen.

Ein Trick war, den Bildausschnitt dynamisch beim Scrollen bzw. in einem zusätzlichen requestAnimationFrame() loop direkt auf einem sichtbaren img-Element über style mit einem dynamisch berechneten clip-path zu beschneiden. Funktioniert am Ende auch wie gedacht. Nur leider kommt es wieder an Ober- und Unterkante der so maskierten Bilder zu einem jitter. Wie beschrieben laufen wir mit unseren Javascript Bemühungen immer einige Frames hinter dem Update des Viewports hinterher. Der Effekt zeigt sich optisch tatsächlich in einer Art zitternden Schleppe beim Scrollen.

Sehr schade eigentlich, da der Einsatz von 3D sicher für alle getesteten Browser und Endgeräte die optimale Wahl wäre. Nur ist man dann im Design auf ganz bestimmte Layouts eingeschränkt. Stellt sich die Frage, warum alle Browserhersteller die Möglichkeit von Maskierung über overflow:hidden oder clip-path explizit ausgeschlossen haben. Das hat sicherlich Performancegründe, da die layer composition aufwändiger ist. Aber wie so oft frage ich mich, warum ein so oft genutztes feature wie Parallax nicht schon längst vollumfänglich nativ gelöst wurde? Letztendlich müssen wieder jahrelang alle Entwickler ihr eigenes Ding zurechtbasteln. Vergl. die von vielen genutzte CSS background-attachment:fixed Variante, die aber auch nur ein Pseudo-Parallax Effekt ist. Und funktioniert wie beschrieben nicht mals in allen mobilen Browsern bzw. nicht ruckelfrei.