German (Deutsch) translation by Federicco Ancie (you can also view the original English article)
Sticky-Preistabellen eignen sich perfekt für die Anzeige von Produkten und Dienstleistungen mit langen Listen vergleichbarer Funktionen. In diesem Tutorial erstellen wir eine Preistabelle mit einem klebrigen Header. Unterwegs lernen wir, wie Sie Elemente nach einem bestimmten Bildlauf fixieren und entfernen.
Es gibt eine Reihe von JavaScript-Plugins, die diese Art von Funktionalität bieten, wie ScrollMagic.js. Tatsächlich habe ich bereits ein Tutorial veröffentlicht, das zeigt, wie Sie mit diesem Plugin einen ähnlichen Effekt implementieren können.
Fordern wir uns heute jedoch selbst heraus und schreiben unseren eigenen Code.
Die Preistabelle, die wir erstellen
Für diese praktische Übung erstellen wir eine Preisseite, auf der die verschiedenen Abonnementpläne in den Spalten einer Preistabelle aufgeführt sind. Wenn wir nach unten scrollen, wird der Header klebrig, um im Blick zu bleiben, und wird zu einem späteren Zeitpunkt freigegeben. Die Preistabelle mit Sticky-Header-Kombination ist ein beliebtes UI-Muster, das Sie möglicherweise auf Websites wie monday.com gesehen haben.
Beachten Sie, dass die klebrige Funktionalität unserer Demo-Trigger in Ansichtsfenstern mit einer Größe von mehr als 779 Pixel angezeigt wird. Möglicherweise müssen Sie sich die Vollbild-Demo ansehen, um sie vollständig zu schätzen!
Wann sollten Sie eine Preistabelle verwenden?
Preistabellen kommen zur Geltung, wenn eine Sammlung von Produkten, Dienstleistungen oder Varianten dem Verbraucher zu viel Auswahl bietet. Wenn der Verbraucher Schwierigkeiten hat, sich für eine Option zu entscheiden, entscheidet er sich eher für nichts. Informationsüberflutung = Konvertierungsfehler.
Zeitverschwendung beim Treffen von Entscheidungen macht jeden Vorteil zunichte, wenn man überhaupt die Wahl hat!
"Untersuchungen [..] zeigen, dass ein Übermaß an Auswahlmöglichkeiten oft dazu führt, dass wir weniger und nicht mehr zufrieden sind, wenn wir uns tatsächlich entscheiden." -
Alina Tugend, NYT
Die Rolle einer Preistabelle besteht darin, dem Benutzer zu helfen, die ihm zur Verfügung stehenden Optionen visuell zu interpretieren, und ihn manchmal sogar zu ermutigen, sich auf die attraktivste Wahl zu konzentrieren.
Weitere Informationen finden Sie in Val Geislers Anleitung zum Entwerfen einer Preisseite, die im InVision-Blog konvertiert wird.
Pricing Table Plugins für WordPress
Bevor Sie in das Tutorial eintauchen, sollten Sie sich die Plugins für Preistabellen ansehen, die für WordPress auf Envato Market verfügbar sind.

Nachdem dies gesagt ist, helfen wir unseren Benutzern jetzt, indem wir eine super klare Tabelle erstellen, aus der sie auswählen können!
1. Beginnen Sie mit dem Seiten-Markup
Wir beginnen mit drei Abschnitten:
<section>...</section> <section>...</section> <section>...</section>
Der erste und dritte Abschnitt spielen keine wichtige Rolle. Sie enthalten Dummy-Inhalte und -Stile, um sicherzustellen, dass die Seite lang genug ist, um den gewünschten Bildlaufeffekt auszulösen.
Im zweiten Abschnitt platzieren wir die Tabelle. Wir werden es in einen Container einwickeln, damit es sich auf kleinen Bildschirmen reaktionsschnell verhält:
<div class="container"> <div class="table-wrapper"> <table> <thead> <tr> <th>...</th> <th>...</th> <th>...</th> <th>...</th> </tr> </thead> <tbody> <tr> <td>...</td> <td>...</td> <td>...</td> <td>...</td> </tr> <!-- more rows here --> </tbody> </table> </div> </div>
Die Tabelle selbst enthält vier Spalten und repräsentiert die Preispläne für ein Produkt oder eine Dienstleistung. In unserem Fall haben wir drei Abonnements: Starter, Essential und Professional.
Tabellenüberschriften
Der klebrige Header der Tabelle identifiziert diese Pläne eindeutig. Jeder Plan enthält auch eine Handlungsaufforderungstaste.

Hier ist das Markup für die Tabellenüberschriften:
<tr> <th> <div> Select your plan <div class="svg-wrapper"> <svg viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm1 17v-4h-8v-2h8v-4l6 5-6 5z"/></svg> </div> </div> </th> <th> <div class="heading">...</div> <div class="info"> <div class="amount">...</div> <div class="billing-msg">...</div> <button type="button">...</button> </div> </th> <th> <div class="heading">...</div> <div class="info"> <div class="popular">...</div> <div class="amount">...</div> <div class="billing-msg">...</div> <button type="button">...</button> </div> </th> <th> <div class="heading">...</div> <div class="info"> <div class="amount">...</div> <div class="billing-msg">...</div> <button type="button">...</button> </div> </th> </tr>
Tabellenzeilen
Jede Tabellenzeile beschreibt die Verfügbarkeit eines Features in allen Plänen. Wenn ein Plan diese Funktion enthält, wird ein SVG-Häkchensymbol angezeigt. Andernfalls wird ein graues Kreuz angezeigt.

Hier ist das Markup für eine Funktion, die von allen Plänen unterstützt wird:
<tr> <td>...</td> <td> <svg class="starter" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg> </td> <td> <svg class="essential" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg> </td> <td> <svg class="professional" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg> </td> </tr>
Und hier ist das Markup für eine Funktion, die nur im "Professional" -Plan verfügbar ist:
<tr> <td>...</td> <td> <svg class="not-included" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z"/></svg> </td> <td> <svg class="not-included" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117 4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16 1.849 1.849-4.1 4.141 4.157 4.104-1.849 1.849z"/></svg> </td> <td> <svg class="professional" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-1.959 17l-4.5-4.319 1.395-1.435 3.08 2.937 7.021-7.183 1.422 1.409-8.418 8.591z"/></svg> </td> </tr>
2. Definieren Sie einige grundlegende Stile
Wenn das Markup fertig ist, werden wir mit dem CSS fortfahren. Unser erster Schritt besteht darin, einige CSS-Variablen und allgemeine Rücksetzstile einzurichten.
Für jeden Plan definieren wir die entsprechende Variable. Dadurch können wir das Erscheinungsbild bei Bedarf leicht ändern.
Hier sind die Reset-Stile:
:root { --white: white; --gray: #999; --lightgray: whitesmoke; --popular: #ffdd40; --starter: #f73859; --essential: #00AEEF; --professional: #FF7F45; } * { padding: 0; margin: 0; box-sizing: border-box; } button { background: none; border: none; cursor: pointer; } table { border-collapse: collapse; } body { font: 18px/1.5 'Noto Sans', sans-serif; background: var(--lightgray); }
Hinweis: Der Einfachheit halber werde ich nicht alle CSS-Regeln im Lernprogramm durchgehen. Hier gibt es fast 290 CSS-Zeilen. Ich werde nur die wichtigsten diskutieren. Stellen Sie sicher, dass Sie alle überprüfen, indem Sie auf die Registerkarte CSS des Demo-Projekts klicken.
3. Gestalten Sie die Preistabelle
Die Preistabelle hat eine maximale Breite und wird horizontal auf der Seite zentriert:
.container { max-width: 850px; padding: 0 10px; margin: 0 auto; } table { width: 100%; }
Die Zeilen verhalten sich wie Flex-Container:
table tr { display: flex; }
Alle Zellen haben die gleiche Breite:
table th, table td { width: 25%; min-width: 150px; }
Um die Pläne zu trennen und eine klare Sicht darauf zu erhalten, welche Zelle zu jedem Plan gehört, fügen wir den Zielelementen einen hellgrauen Rand hinzu:
--lightgray: whitesmoke; table th .info, table td:not(:first-child) { border-left: 1px solid var(--lightgray); }
Die Preistabelle reaktionsschnell machen
Wie wir im nächsten Abschnitt sehen werden, wird der Sticky-Effekt in Ansichtsfenstern mit mehr als 779 Pixel ausgelöst (Sie können diesen Wert entsprechend ändern). In kleineren Ansichtsfenstern wird eine typische Tabelle angezeigt, die horizontal gescrollt werden kann.

Bootstrap verwendet ähnliche Funktionen auch für responsive Tabellen. Es gibt andere (bessere?) Ansätze für den Umgang mit reaktionsschnellen Tabellen, aber diese Methode macht hier sicherlich den Job.
4. Stecken Sie den Tabellenkopf fest / entfernen Sie ihn
Mit HTML und CSS konzentrieren wir uns jetzt auf den Bildlaufeffekt mit JavaScript. Dadurch können wir unseren Header klebrig machen.
Variablen
Für unseren ersten Schritt holen wir uns eine Kopie der gewünschten Elemente. Wir speichern die beiden Klassen, die wir später verwenden werden, in Variablen:
const body = document.body; const firstSection = document.querySelector("section:nth-child(1)"); const lastSection = document.querySelector("section:nth-child(3)"); const table = document.querySelector("table"); const thead = document.querySelector("table thead"); const mq = window.matchMedia("(min-width: 780px)"); const stickyClass = "sticky-table"; const sticky2Class = "sticky2-table";
Der nächste Schritt besteht darin, einige Berechnungen durchzuführen. Insbesondere möchten wir die folgenden Dinge berechnen:
- Die Tischbreite.
- Die oberste Position der Tabelle relativ zum Ansichtsfenster.
- Die Höhe des
thead
. Dies ist das Element, das fixiert / nicht fixiert wird.
Hier ist das erforderliche JavaScript, um dies zu tun:
let tableWidth = table.offsetWidth; let tableOffsetTop = table.getBoundingClientRect().top; let theadHeight = thead.offsetHeight;
Beachten Sie, dass wir die oben genannten Werte in let
-Variablen speichern. Wir haben das absichtlich gemacht. Wenn die Größe der Seite geändert wird, sollten wir das oben beschriebene Material neu berechnen und diesen Variablen diese neuen Werte neu zuweisen.
Beim Scrollen
Jedes Mal, wenn wir nach oben oder unten scrollen, wird die Funktion scrollHandler
ausgeführt:
Innerhalb dieser Funktion führen wir die folgenden Aktionen aus, die nur ausgeführt werden, wenn die Fensterbreite mindestens 780 Pixel beträgt:
- Rufen Sie die Anzahl der Pixel ab, die ein Benutzer vom oberen Rand des Ansichtsfensters gescrollt hat.
- Holen Sie sich die oberste Position des letzten Abschnitts relativ zum Ansichtsfenster.
- Überprüfen Sie, ob ein Benutzer mehr als oder gleich der anfänglichen oberen Position der Tabelle gescrollt hat.
- In diesem Fall setzen wir die Breite des
thead
gleich der Anfangsbreite der Tabelle. - Dann prüfen wir, ob der resultierende Wert von Schritt 2 größer als die Höhe des
thead
ist. - In diesem Fall fixieren wir das
thead
-Element, indem wir diesticky-table
-Klasse zumbody
hinzufügen und diesticky-table2
-Klasse aus demselben Element entfernen. An diesem Punkt wird derthead
zu einem fest positionierten Element. Wir positionieren es dann oben im Ansichtsfenster. Wir geben dembody
auch eine obere Polsterung, die der Höhe desthead
entspricht. - Wenn dies nicht der Fall ist, hören wir auf, den
thead
zu fixieren, indem wir die Klassesticky-table2
zumbody
hinzufügen und die Klassesticky-table
aus demselben Element entfernen. An diesem Punkt wird derthead
freigegeben und wird zu einem absolut positionierten Element. Wir positionieren es dann am Ende der Tabelle. - Falls ein Benutzer weniger als die ursprüngliche obere Position der Tabelle gescrollt hat (der
thead
wurde noch nicht fixiert), entfernen wir die Klassensticky-table
undstick-table2
aus dembody
. Außerdem setzen wir die obere Polsterung auf 0. Zu diesem Zeitpunkt hat derthead
keine Position (statisches Element), daher setzen wir seine standardmäßigetop
Position zurück. Schließlich setzen wir seine Breite auf 100% (wir können es überspringen).
Der Code, der all dieses Verhalten implementiert, lautet wie folgt:
window.addEventListener("scroll", scrollHandler); function scrollHandler() { if (mq.matches) { // 1 const scrollY = window.pageYOffset; // 2 const lastSectionOffsetTop = lastSection.getBoundingClientRect().top; // 3 if (scrollY >= tableOffsetTop) { // 4 thead.style.width = `${tableWidth}px`; // 5 if (lastSectionOffsetTop > theadHeight) { // 6 body.classList.remove(sticky2Class); body.classList.add(stickyClass); thead.style.top = 0; body.style.paddingTop = `${theadHeight}px`; } else { // 7 body.classList.remove(stickyClass); body.classList.add(sticky2Class); thead.style.top = `calc(100% - ${theadHeight}px)`; } } else { // 8 body.classList.remove(stickyClass, sticky2Class); body.style.paddingTop = 0; thead.style.width = "100%"; thead.style.top = "auto"; } } }
Und die zugehörigen Stile für jede Klasse:
table thead { transition: box-shadow 0.2s; } .sticky-table table thead { position: fixed; left: 50%; transform: translateX(-50%); } .sticky-table table thead { box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.12); } .sticky2-table table thead { position: absolute; left: 0; }
5. Ändern der Größe der Seite
Wir haben den Job fast erledigt, Leute! Bisher funktioniert der Sticky-Header-Effekt beim Laden der Seite einwandfrei. Aber was passiert, wenn die Größe der Seite geändert wird? Nun, es wäre wirklich schön, wenn wir diese Demo auch für die Größenänderung verwenden könnten, oder? Machen wir das!
Jedes Mal, wenn wir die Größe der Seite ändern, wird die Funktion resizeHandler
ausgeführt.
Innerhalb dieser Funktion überprüfen wir zuerst die Fensterbreite, aktualisieren dann entweder die Werte der oben genannten let
-Variablen oder setzen die Inline-Stile für thead
und body
zurück. Beachten Sie, dass wir die oberste Position des Tisches abrufen, indem wir die Höhe des ersten Abschnitts ermitteln. Sie fragen sich vielleicht, warum wir die offsetTop
-Eigenschaft der Tabelle nicht verwendet haben? Während meiner Tests ist mir aufgefallen, dass beim Ändern der Größe nicht immer genaue Ergebnisse erzielt werden. Außerdem funktioniert die Methode getBoundingClientRect()
nicht, da sie auch falsche (sogar negative) Werte liefert.
Der erforderliche JavaScript-Code:
window.addEventListener("resize", resizeHandler); function resizeHandler() { if (mq.matches) { tableWidth = firstSection.offsetHeight; tableOffsetTop = table.offsetTop; theadHeight = thead.offsetHeight; } else { body.classList.remove(stickyClass, sticky2Class); body.style.paddingTop = 0; thead.style.width = "100%"; thead.style.top = "auto"; } }
Abschluss
Das war's Leute! In diesem Tutorial ist es uns gelungen, einen nützlichen Bildlaufeffekt zu erstellen, ohne eine externe Bibliothek zu verwenden. Wir haben nicht nur gelernt, wie man klebrige Elemente erstellt, sondern auch, wie man sie nach einer gewissen Zeit des Scrollens löst (freigibt).
All dies zusammen hat uns eine wirklich nützliche Preistabelle mit einem klebrigen Header gegeben.
Ich hoffe, dass diese Übung Ihnen geholfen hat, etwas Neues zu lernen, und Sie dazu inspiriert hat, es in einem bevorstehenden Projekt zu verwenden.
Vor dem Schließen möchte ich zwei Dinge hervorheben:
- Ich habe das
table
-Element verwendet, um diesen Effekt zu erstellen. Dies ist möglicherweise nicht immer die ideale Methode, wenn man bedenkt, dass es heute flexiblere und leistungsfähigere Layoutlösungen wie CSS Grid gibt. Eine Tabelle ist jedoch oft das beste Element für die Anzeige von Daten, daher habe ich mich bei dieser Gelegenheit dafür entschieden. - Es ist immer eine große Herausforderung, tabellarische Daten auf Mobilgeräten darzustellen. Bei dieser Gelegenheit habe ich mich für eine einfache Bildlauflösung entschieden. Ein anderer Ansatz könnte darin bestehen, die Tabellenmethode für eine Karusselllösung mit drei Folien, bei denen jede Folie einen Preisplan darstellt, vollständig zu verwerfen (nur > 779px). Vielleicht haben Sie eine bessere Idee, die wir in den Kommentaren unten diskutieren könnten.
Wie immer vielen Dank fürs Lesen!
Weitere Sticky Tutorials
Wir haben einige Tutorials, die verschiedene Ansätze zum Kleben von Elementen beim Scrollen einer Webseite untersuchen:
- CSSSticky Positioning ohne JavaScript (Dank CSS Position: Sticky)Thoriq Firdaus
- jQuerySchneller Tipp: Sticky Navigation, ohne den umständlichen SprungAdi Purdila
- HTMLSo verstecken Sie einen klebrigen Header beim Scrollen (mit JavaScript)George Martsoukos
- MusterSo erstellen Sie einen festen Header, der beim Scrollen der Seite animiert wirdGeorge Martsoukos
Weitere Informationen zu Preistabellen
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post