Besuchen Sie unseren Adventskalender 2022!

OnePager

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Single-Page-Webseiten oder OnePager (auch als pageless Design bekannt) sind gerade für Web-Visitenkarten, Landing Pages und kleinere Projekte perfekt geeignet.

Bei Single-Page-Webseiten wird der Inhalt nicht auf mehrere kurze Seiten verteilt, sondern auf einer einzigen "langen" Seite sofort geladen und durch Scrollen oder Navigieren ohne weiteren HTTP-Request eingeblendet.

Allerdings wird dieser potentielle Geschwindigkeitsvorteil durch den Einsatz von Frameworks oft in sein Gegenteil verkehrt, wenn erst mehrere MB geladen werden müssen, um die Funktionalität einer einzelnen Seite herzustellen. In diesen Beispielen sehen Sie, wie Sie eine solche Seite nur mit CSS realisieren können.

Vorüberlegungen

OnePager sind sinnvoll, wenn Sie einen klar umrissenen Inhalt von einigen Abschnitten haben. Das kann eine Landing Page, eine Web-Visitenkarte oder eine Präsentation eines neuen Produkts oder einer Recherche sein. Ein Beispiel wird im Abschnitt Interactive Storytelling gezeigt. Umfangreichere Webprojekte oder nicht thematisch zusammengehörende Seiten sollten besser mit klassischen Einzelseiten realisiert werden.[1][2]

Die Bedienung eines One-Pagers sollte so einfach wie möglich sein. Das Scrollen mit Maus und Wischgeste führt die Benutzer intuitiv zu weiteren Inhalten. Trotzdem sollte es in den einzelnen Bereichen Wegweiser für die weitere Nutzung geben - besonders wenn es mehrere Möglichkeiten gibt - wie z. B. ein mögliches horizontales Scrollen zur Seite.

HTML-Grundstruktur

HTML-Grundstruktur
<section id="part_1">
  <h1>One-Pager ohne JavaScript</h1>
  ...
</section>
  
<section id="part_2">
  <h2>Gruppen</h2>
  ...
</section>

...

<nav>	
	<ul id="navigation">
		<li><a href="#part_1">Startseite</a></li>
		<li><a href="#part_2">Gruppen</a></li>
		<li><a href="#part_3">Wunder</a></li>
		<li><a href="#part_4">Finale</a></li>
		<li><a href="#part_5">?</a></li>
	</ul>
</nav>

Diese Webseite besteht aus mehreren Seiten(bereichen), die in section-Elementen untereinander notiert sind. Diese werden mit einer eindeutigen id ausgezeichnet.

Die Navigation besteht aus internen Ankern, , die auf diese id-Anker referenzieren.

One-Pager mit FadeIn

In diesem Beispiel sollen die jeweils ausgewählten Inhalte eingeblendet werden.[3]

Sobald eine Seite durch einen Klick oder Tap auf den entsprechenden Verweis als Ziel (target) aktiviert ist, kann man diese mit CSS über die strukturelle Pseudoklasse :target sichtbar machen.

CSS: Beschränkung auf den ausgewählten Seitenbereich

Im oberen Beispiel lassen sich zwar alle Seitenbereiche durch die Navigation ansteuern; die Navigation ist dann allerdings nicht mehr sichtbar. Im folgenden Beispiel erhält nun die Seite eine Höhe von 100vh, sodass jeweils nur der ausgewählte Seitenbereich sichtbar ist.

Beispiel ansehen …
body {
	position: relative;
	overflow: hidden;
	height: 100vh;
}
 
section {
	padding:3em 1em 1em;
	width:100%;
	height: 100vh;
	background: white;	
}

Sowohl der body als auch die section-Elemente erhalten eine Höhe von 100vh. Dies entspricht der aktuellen Viewportabmessung. Durch die Festlegung overflow: hidden; werden Seitenbereiche, die außerhalb des Viewports liegen nicht angezeigt. Es kann aber auch nicht dorthin gescrollt werden.

Beachten Sie:

Dieses Beispiel würde ich heute so nicht mehr realisieren:

  • Nutzer können nicht nach unten scrollen, was den Konventionen widerspricht.
  • Auf kleinen Viewports sind nicht alle Inhalte sichtbar.
--Matthias Scharwies (Diskussion) 05:46, 11. Dez. 2022 (CET)


Beim Umschalten zwischen den einzelnen Seitenbereichen kommt es zu einem abrupten Übergang.

CSS: weiche Übergänge mit Einblendungen

Beispiel ansehen …
body {
	position: relative;
	overflow: hidden;
	height: 100vh;
}
 
section {
	padding:3em 1em 1em;
	width:100%;
	height: 100vh;	
	background: white;	
	opacity: 0;
	position: absolute;
	top: 0;
	left: 0;
	transition: all 0.5s;
}
 
section:first-of-type {
  opacity: 1;
  transition: all 0.5s;
}
 
section:target {
  opacity: 1;
 
}

Alle Seitenbereiche werden nun absolut übereinander positioniert. Durch opacity: 0; sind sie völlig durchscheinend bis auf das erste Element, das durch die strukturelle Pseudoklasse first-of-type sichtbar ist.

Wenn nun ein Seitenbereich mit dem Klick auf den entsprechenden Link ausgewählt wird, erhält er die Pseudoklasse target und wird entsprechend mit CSS formatiert. Diese Änderung der Deckkraft wird mit transition: all 0.5s; mit einem weichen Übergang versehen.

Fazit: Die Seite blendet die einzelnen „Seiten“ immer wieder ein. Allerdings kann man mit dem Zurück-Button des Browsers nicht zur vorherigen Seite, sondern nur zur vorherigen Ansicht wechseln. Des Weiteren ist die Seitengröße durch den Viewport festgelegt. Ein Hinzufügen von weiteren Inhalten in ein section-Element birgt die Gefahr wegen des overflow: hidden Inhalte nicht mehr darzustellen.

„Könnte man nicht einen One-Pager erstellen, in dem die section-Elemente eine flexible Länge erhalten?“

One-Pager mit Scroll Snap

Benutzer, die auf mobilen Geräten mit Touchscreen surfen, sind es gewohnt weitere Inhalte mit einem Wisch in den sichtbaren Bereich zu holen. Deshalb sollen die einzelnen Sektionen im nächsten Beispiel untereinander in ihrer normalen Reihenfolge angeordnet werden. Ein Wisch (oder eine Mausbewegung oder ein Klick in der Navigation) verschiebt den Inhalt und führt zum nächsten Abschnitt. Schön wäre, wenn nicht impulsiv bis zum Seitenende gescrollt wird, sondern an der nächsten Überschrift automatisch angehalten werden kann.

Diese Technologie nennt sich Scroll Snap. Beim Scrollen rastet der Browser an bestimmten Stellen im Layout ein, wenn über diese Punkte hinweg gescrollt werden soll. Während dies früher den Einsatz von JavaScript und jQuery erforderte, reicht heute allein CSS.

Browserunterstützung
caniuse.com

Das HTML-Markup besteht wie im vorherigen Beispiel aus einer Navigation und mehreren Abschnitten innerhalb von section-Elementen. Die section-Elemente erhalten zusätzlich einen tabindex, damit sie auch mit der Tastatur angesteuert werden können.[4]

Scroll Snap benötigt einen Scroll-Container, in dem gescrollt werden soll und mehrere Kindelemente, die verschiebbar sein sollen.

Onepager mit Scroll Snap ansehen …
@media (prefers-reduced-motion: no-preference) {
  body {
    margin: 0;
    scroll-snap-type: y mandatory; 
    scroll-behavior: smooth;
    scroll-padding: 0; /* nicht nötig */
  }

  section {
    height: 100vh;
    scroll-snap-align: start; 
    scroll-margin: 0;  /* nicht nötig */
  }
}

Der body hat 2 neue Regelsätze:

  • scroll-snap-type hat 2 Parameter:
    • y legt fest, dass der Scroll-Container in y-Richtung, also nach unten gescrollt wird.
    • mandatory legt fest, dass am nächsten Fangpunkt eingerastet wird.
  • scroll-behavior spezifiziert das Scroll-Verhalten einer Scroll-Box, wenn ein Scroll-Event durch eine Navigation ausgelöst wird. Dass heißt, wenn ein interner Seitenanker auf eine section-klick, kommt es nicht zu einem plötzlichen Übergang, sondern ebenfalls zu einem Runterscrollen.
  • scroll-padding legt einen (möglichen) Innenabstand innerhalb des Scroll-Containers fest.

Die section-Elemente haben ebenfalls neue Eigenschaften:

  • scroll-snap-align legt mit dem Wert start fest, dass sich die Fangposition am Anfang der Scroll-Box befindet.
  • scroll-margin legt einen (möglichen) Außenabstand außerhalb des Fangpunktes der Scroll-Box fest.

Diese Regelsätze sind innerhalb einer Medienabfrage verschachtelt.

  • Sind keine Festlegungen für prefers-reduced-motion getroffen, wird gescrollt.
  • Falls der Benutzer dies in seinem Betriebssystem so angegeben hat, wird auf das Scollen verzichtet (→ Der Benutzer erhält die Kontrolle, wie die Webseite bei ihm animiert wird.)

Exkurs: Bildergalerie mit horizontalem Scrollen

Diese Bildergalerie lässt sich entlang der X-Achse horizontal scrollen. Dafür war früher einiges an JavaScript notwendig - heute benötigt man nur wenige Zeilen CSS:

horizontales Scrollen ansehen …
.gallery {
    display: flex;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
}

.gallery img {
    scroll-snap-align: center;
}

Alle Elemente, die sich im Container-Element mit der Klasse gallery befinden, werden nun horizontal angeordnet:

  • display:flex: erzeugt einen flexiblen Container, in dem sich alle Kindelemente (die Bilder) gleichmäßig verteilen
  • overflow-y: hidden: sorgt, dafür, dass außerhalb des Containers befindliche Elemente nicht angezeigt werden.

Für den Scroll Snap benötigen sowohl der Container als auch die scrollenden Elemente jeweils nur eine Festlegung:

  • scroll-snap-type für den Scroll-Container
    • x Das Scrollen soll entlang der X-Achse, also horizontal erfolgen
    • mandatory erzwingt das Einschnappen an der Fangposition
  • scroll-snap-align legt für die Kindelemente fest, wo sich die Fangposition befindet
    • center Die Fangposition befindet sich in der Mitte der Scrollelemente, die Bilder werden nach dem Scroll Snap also zentriert angezeigt


Fazit

Die hier nur mit CSS realisierten Alternativen sind voll funktionsfähig. Allerdings lassen sich einige Extras wie Weiter-Links nur mit vielen Zeilen CSS realisieren und sind dann schwer zu erweitern, bzw. fehlen wie das Lazy-Loading gegenüber einer mit JavaScript erweiterten Variante.

Mit Hilfe der Intersection-Observer-API könnte man den aktuell sichtbaren Teil der Webseite identifizieren und dann den entsprechenden Seitenanker in der Navigation mit aria-current auszeichnen sowie Links zum nächsten Kapitel erzeugen.

Einen anderen Ansatz verfolgen progressive Web Apps - eigentlich auch One-Pager. Jedoch werden dort die Seiteninhalte per JavaScript erzeugt und wieder entfernt.

Hauptartikel: JavaScript/Tutorials/App

Weblinks

  1. Jan Semler: Single-Page Website und wie man es richtig macht (28.01.2013)
  2. onepager.de (umfangreiche Erklärung aus Sicht der Werbeagenturen)
  3. One Page CSS-Only Navigation by Alberto Hartzet
  4. a11yproject.com: Scrollable Overflow containers