Einführung: Warum ein dynamischer Preistabelle wichtig ist

Preistabellen sind ein Eckpfeiler jeder Produkt- oder Service-Website. Eine statische, einheitliche Tabelle kann Ihre Preispunkte darstellen, aber eine dynamische Preistabelle - eine, die in Echtzeit basierend auf Benutzerinteraktionen aktualisiert wird - kann die Conversion-Rate deutlich steigern. Indem Besucher zwischen monatlicher und jährlicher Abrechnung wechseln, die Gesamtkosten mit Add-ons sehen oder Funktionen interaktiv vergleichen, erstellen Sie eine transparente und ansprechende Erfahrung. In diesem Handbuch erstellen wir eine produktionsbereite dynamische Preistabelle mit einfachem JavaScript und CSS-Grid. Keine Frameworks, keine Bibliotheken - nur solider, wartbarer Code, der über moderne Browser funktioniert.

Einrichten der HTML-Struktur für ein Preisraster

Die Grundlage jeder dynamischen Preistabelle ist eine saubere, semantische HTML-Struktur. Wir beginnen mit einem Container, der unser CSS-Grid wird, und verschachteln dann einzelne Preiskarten darin. Jede Karte sollte den Plannamen, den Preis, eine Liste von Funktionen und einen Call-to-Action-Button enthalten. Um dynamische Updates zu ermöglichen, fügen wir auf jeder Karte ein -Attribut hinzu und strukturieren den Preiscontainer mit einer Klasse, auf die wir mit JavaScript abzielen können.

<div class="pricing-grid" role="group" aria-label="Pricing plans">
 <div class="pricing-card" data-plan="basic">
 <h3 class="plan-name">Basic</h3>
 <p class="price">
 <span class="amount">$10</span>
 <span class="period">/mo</span>
 </p>
 <ul class="features">
 <li>5 projects</li>
 <li>10 GB storage</li>
 <li>Basic support</li>
 </ul>
 <a href="#" class="btn">Get Started</a>
 </div>
 <div class="pricing-card featured" data-plan="pro">
 <h3 class="plan-name">Pro</h3>
 <p class="price">
 <span class="amount">$25</span>
 <span class="period">/mo</span>
 </p>
 <ul class="features">
 <li>Unlimited projects</li>
 <li>100 GB storage</li>
 <li>Priority support</li>
 </ul>
 <a href="#" class="btn">Get Started</a>
 </div>
 <div class="pricing-card" data-plan="enterprise">
 <h3 class="plan-name">Enterprise</h3>
 <p class="price">
 <span class="amount">$50</span>
 <span class="period">/mo</span>
 </p>
 <ul class="features">
 <li>Unlimited projects</li>
 <li>1 TB storage</li>
 <li>24/7 support</li>
 </ul>
 <a href="#" class="btn">Contact Sales</a>
 </div>
</div>

Beachten Sie die und , um die Zugänglichkeit zu verbessern.

Erstellen des CSS-Grid-Layouts

CSS Grid macht es einfach, ein responsives Raster zu erstellen, das die Anzahl der Spalten basierend auf dem Viewport anpasst. Wir definieren den Container als Raster, legen eine flexible Anzahl von Spalten mit und fest und fügen Abstand mit hinzu. Innerhalb jeder Karte verwenden wir CSS Grid intern, um den Preis, die Funktionen und die Schaltfläche auszurichten.

.pricing-grid {
 display: grid;
 grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
 gap: 1.5rem;
 max-width: 1200px;
 margin: 0 auto;
 padding: 2rem;
}

.pricing-card {
 display: grid;
 grid-template-rows: auto auto 1fr auto;
 border: 1px solid #e0e0e0;
 border-radius: 12px;
 padding: 2rem;
 text-align: center;
 background: #fff;
 transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.pricing-card:hover {
 transform: translateY(-4px);
 box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}

.pricing-card.featured {
 border: 2px solid #007bff;
 position: relative;
}

.pricing-card.featured::before {
 content: "Most Popular";
 position: absolute;
 top: -12px;
 left: 50%;
 transform: translateX(-50%);
 background: #007bff;
 color: #fff;
 padding: 4px 16px;
 border-radius: 20px;
 font-size: 0.8rem;
 font-weight: 600;
}

.plan-name {
 font-size: 1.5rem;
 margin: 0 0 0.5rem;
}

.price {
 margin: 0 0 1.5rem;
}

.amount {
 font-size: 2.5rem;
 font-weight: 700;
}

.period {
 font-size: 1rem;
 color: #666;
}

.features {
 list-style: none;
 padding: 0;
 margin: 0 0 1.5rem;
}

.features li {
 padding: 0.5rem 0;
 border-bottom: 1px solid #eee;
}

.features li:last-child {
 border-bottom: none;
}

.btn {
 display: inline-block;
 padding: 0.75rem 1.5rem;
 background: #007bff;
 color: #fff;
 text-decoration: none;
 border-radius: 8px;
 transition: background 0.3s;
}

.btn:hover {
 background: #0056b3;
}

Das stellt sicher, dass der Button immer unten bleibt, auch wenn Feature-Listen unterschiedlich lang sind.

Hinzufügen der JavaScript Interaktivität

Jetzt kommt der dynamische Teil. Wir fügen einen Umschalter hinzu, der es Besuchern ermöglicht, zwischen monatlichen und jährlichen Preisen zu wechseln. Wenn sich der Umschalter ändert, aktualisiert JavaScript die Preise für alle Karten. Wir fügen auch einen Helfer zum Formatieren von Preisen und einen reibungslosen Übergang für die numerische Änderung hinzu.

<div class="pricing-toggle">
 <label class="toggle-label">
 <span>Monthly</span>
 <input type="checkbox" id="billing-toggle" role="switch" aria-checked="false">
 <span class="toggle-slider"></span>
 <span>Yearly (save up to 20%)</span>
 </label>
</div>

CSS für den Toggle:

.pricing-toggle {
 text-align: center;
 margin-bottom: 2rem;
}

.toggle-label {
 display: inline-flex;
 align-items: center;
 gap: 0.75rem;
 cursor: pointer;
 user-select: none;
}

.toggle-label input[type="checkbox"] {
 position: absolute;
 opacity: 0;
 width: 0;
 height: 0;
}

.toggle-slider {
 width: 50px;
 height: 26px;
 background: #ccc;
 border-radius: 13px;
 position: relative;
 transition: background 0.3s;
}

.toggle-slider::after {
 content: "";
 position: absolute;
 top: 3px;
 left: 3px;
 width: 20px;
 height: 20px;
 background: white;
 border-radius: 50%;
 transition: transform 0.3s;
}

input:checked + .toggle-slider {
 background: #007bff;
}

input:checked + .toggle-slider::after {
 transform: translateX(24px);
}

JavaScript, das das Update unterstützt:

document.addEventListener('DOMContentLoaded', () => {
 const toggle = document.getElementById('billing-toggle');
 const prices = {
 basic: { monthly: 10, yearly: 8 }, // per month when billed yearly
 pro: { monthly: 25, yearly: 20 },
 enterprise: { monthly: 50, yearly: 40 }
 };

 function updatePrices(isYearly) {
 document.querySelectorAll('.pricing-card').forEach(card => {
 const plan = card.dataset.plan;
 if (!plan || !prices[plan]) return;
 const amountElement = card.querySelector('.amount');
 const periodElement = card.querySelector('.period');
 let amount, period;
 if (isYearly) {
 amount = prices[plan].yearly;
 period = ' /mo (billed yearly)';
 } else {
 amount = prices[plan].monthly;
 period = ' /mo';
 }
 amountElement.textContent = `$${amount}`;
 periodElement.textContent = period;
 });
 }

 toggle.addEventListener('change', () => {
 const isYearly = toggle.checked;
 updatePrices(isYearly);
 toggle.setAttribute('aria-checked', isYearly);
 });

 // Initialize with monthly
 updatePrices(false);
});

Das Objekt speichert sowohl monatliche als auch jährliche Preise. Jährliche Preise repräsentieren die monatlichen Kosten bei jährlichen Zahlungen - ein gemeinsames Muster. Die Funktion iteriert über jede Karte, liest ihre und aktualisiert den angezeigten Betrag und Zeitraum. Wir aktualisieren auch das -Attribut, um den Schalter zugänglich zu halten.

Den Übergang verbessern

Damit sich die Preisänderung reibungslos anfühlt, können wir einen kurzen CSS-Übergang in den Elementen und hinzufügen. Da sich jedoch sofort ändert, können wir einen Count-Up-Effekt mit einem kleinen Intervall simulieren oder einfach ein Fade-In verwenden. Für eine Produktionsstätte funktioniert ein schneller Opazitätsübergang im Preiscontainer gut. Fügen Sie dies Ihrem CSS hinzu:

.price {
 transition: opacity 0.2s ease;
}

.updating .price {
 opacity: 0;
}

Dann in JavaScript, kurz hinzufügen und entfernen Sie die Klasse auf jeder Karte. aber für die meisten Anwendungsfälle, die sofortige Aktualisierung ist in Ordnung.

Machen Sie den Tisch reaktionsschnell und zugänglich

CSS-Gitter bereits behandelt Reaktionsfähigkeit, aber stellen Sie sicher, dass auf sehr kleinen Bildschirmen die Karten in einer einzigen Spalte stapeln. Der Wert tut das automatisch. Für die Zugänglichkeit müssen wir sicherstellen, dass der Schalter mit der Tastatur bedienbar ist und seinen Zustand ankündigt. Die und haben wir bereits hinzugefügt, um Bildschirmleser zu unterstützen.

Zusätzlich ein sichtbarer Fokusindikator für Tastaturbenutzer. Die Standard-Umrisse funktionieren, aber Sie können sie so gestalten, dass sie Ihrem Branding entsprechen:

.toggle-label input:focus-visible + .toggle-slider {
 outline: 2px solid #007bff;
 outline-offset: 4px;
}

Testen Sie die Preistabelle mit einem Bildschirmleser, um zu überprüfen, ob Preisänderungen angekündigt werden.Um dies zu verbessern, können Sie nach der Aktualisierung des Preises eine Live-Region verwenden:

<div aria-live="polite" aria-atomic="true" class="sr-only"></div>

Setzen Sie dann in JavaScript nach jedem Umschalten den Text auf etwas wie „Preise aktualisiert auf Jahresabrechnung. Dieses Screen-Reader-Element gibt die Änderung ohne visuelle Störung bekannt.

Hinzufügen weiterer dynamischer Funktionen

Sobald der Core-Toggle funktioniert, können Sie die Preistabelle mit zusätzlicher Interaktivität erweitern:

Feature Toggles

Kontrollkästchen für Add-ons (z. B. Extra-Speicherplatz, Teammitglieder) hinzufügen, die den Gesamtpreis aktualisieren. Die Basispreise und Add-on-Kosten in einem Objekt speichern. Wenn sich ein Kontrollkästchen ändert, berechnen Sie die Gesamtsumme für jede Karte entsprechend neu.

Währungsauswahl

Wenn Ihre Zielgruppe global ist, fügen Sie eine Dropdown-Option hinzu, um zwischen USD, EUR, GBP usw. zu wechseln. Speichern Sie die Konversionsraten und multiplizieren Sie den Basispreis. Aktualisieren Sie den -Text mit der richtigen Währungsformatierung mit .

Animierte Preiszähler

Für einen polierten Effekt animieren Sie die Zahl vom alten Wert zum neuen Wert über einige hundert Millisekunden. Bibliotheken wie animate.css sind nicht erforderlich – eine einfache Schleife funktioniert.

Sparausweis

Wenn die jährliche Abrechnung umgedreht wird, zeigen Sie neben dem Preis ein "Save 20%" -Abzeichen an. Berechnen Sie die Einsparungen als und zeigen Sie es dynamisch an. Fügen Sie jeder Karte im HTML ein -Attribut hinzu und lassen Sie es JavaScript füllen oder berechnen Sie es im laufenden Betrieb.

Leistungsbetrachtungen

Mit nur wenigen Preiskarten ist die Leistung kein Problem. Aber wenn Sie Dutzende von Plänen haben (z. B. SaaS, das Pläne aus einer Datenbank generiert), sollten Sie diese Optimierungen berücksichtigen:

  • Verwenden Sie Ereignisdelegation: Fügen Sie einen Ereignishörer anstelle jeder Karte einem übergeordneten Container bei. Für den Umschalter ist das bereits erledigt. Für Kontrollkästchen in Karten, Delegieren.
  • Cache-DOM-Referenzen: Speichern Sie bei der Initialisierung Verweise auf die Elemente und in einem Array oder einer Karte nach Planschlüssel.
  • Verwenden Sie für Animationen: Zeitplan für visuelle Updates für den nächsten Farbzyklus, um Layout-Thrashing zu vermeiden.
  • Reflows minimieren: Batch DOM ändert sich, wenn wir mehrere Karten aktualisieren. In unserer Funktion lesen und schreiben wir das DOM in einer einzigen Schleife – das ist in Ordnung. Wenn Sie Klassen oder Inline-Stile hinzufügen, sollten Sie zuerst alle Werte lesen und dann alle Änderungen schreiben.

Real-World Use Cases und Beispiele

Dynamische Preistabellen werden überall verwendet, von Abonnementdiensten wie Dropbox und Spotify bis hin zu Hosting-Anbietern wie DigitalOcean. Ein gängiges Muster ist es, einen monatlichen / jährlichen Umschalter mit einem “Best Value” -Label auf der jährlichen Option anzubieten. Einige Unternehmen zeigen auch eine jährliche Gesamtgebühr neben den monatlichen Einsparungen. Zum Beispiel könnte ein $ 10 / mo-Plan mit jährlicher Abrechnung “ $ 8 / mo - abgerechnet $ 96 jährlich” anzeigen. Unsere Struktur unterstützt dies bereits mit der Spanne.

Eine weitere Variante sind gleitende Skala für die Menge. Eine Preistabelle für ein SaaS-Produkt kann Schieberegler für die Anzahl der Benutzer oder den Speicher haben. Wenn der Benutzer den Schieberegler bewegt, werden die Preisaktualisierungen live. CSS-Grid übernimmt das Layout und JavaScript aktualisiert die Preiswerte. Dies kann nach den gleichen Prinzipien aufgebaut werden: Preisstufen speichern, Eingabeänderungen hören und das DOM aktualisieren.

Für einen fortschrittlicheren Ansatz könnten Sie Preisdaten aus einer JSON-Datei oder API laden, wodurch die Tabelle wirklich datengesteuert wird. Wenn Ihre Website mit einem Headless-CMS wie Directus erstellt wird, würden die Preisdaten aus einer Sammlung stammen und Ihr Front-End-Javascript würde sie abrufen und das Raster dynamisch darstellen. Dieser Ansatz hält die Preisgestaltung synchron mit Ihrem Backend.

Testen und Browser-Support

CSS Grid wird in allen modernen Browsern unterstützt, einschließlich Internet Explorer 11 mit dem Präfix – obwohl wir empfehlen, Autoprefixer zu verwenden oder IE11 für neue Projekte zu ignorieren. Das hier verwendete JavaScript (ES6 , , Pfeilfunktionen, , Vorlagenliterale) funktioniert in Chrome, Firefox, Safari und Edge. Wenn Sie ältere Browser unterstützen müssen, transpile mit Babel oder verwende und traditionelle Funktionen. Das wird in modernen Bildschirmlesern gut unterstützt, aber Sie können auch ein Standard-Checkbox mit einer versteckten Region als Ausweichmöglichkeit verwenden.

Alternativer Ansatz: CSS-Grid mit CSS-Custom Properties

Eine interessante Methode, um JavaScript für das Umschalten von Preisen zu vermeiden, ist die Verwendung von CSS Custom Properties und (wenn die Browserunterstützung reift). Sie würden die Preise als usw. festlegen und sie ändern, indem Sie eine Klasse auf dem Körper umschalten. Für echte dynamische Logik (z. B. Hinzufügen von zwei Add-ons) ist JavaScript jedoch immer noch erforderlich. Die Kombination von beiden - CSS für Layout und Übergänge, JavaScript für dynamische Daten - ist die robusteste.

Schlussfolgerung

Der Aufbau einer dynamischen Preistabelle mit JavaScript und CSS Grid ist sowohl erreichbar als auch erweitert. Indem Sie mit semantischem HTML beginnen, das Raster mit CSS Grid strukturieren und einfaches JavaScript für Interaktivität hinzufügen, erstellen Sie ein Tool, das sich an komplexe Preismodelle ohne aufgeblähte Abhängigkeiten anpassen kann. Die gleichen Prinzipien - datengesteuerte Updates, responsives Layout, zugängliche Steuerungen - skalieren Sie auf Anwendungen auf Unternehmensebene. Als nächsten Schritt sollten Sie die MDN CSS Grid-Dokumentation lesen, um weitere Techniken zu finden, oder Sara Soueidans Design für barrierefreie erste UmschalterSara Soueidans Design für den Umgang mit komplexen Datenbindungen ohne Framework bietet das Vanilla JS Toolkit bietet leichte Helfer.

Implementieren Sie diese Muster nun in Ihrem eigenen Projekt. Ihre Benutzer werden die Klarheit schätzen und Ihre Conversion-Raten können es Ihnen danken.