Table of Contents
Inleiding: Waarom een dynamische prijstabel belangrijk is
Prijzentabellen zijn een hoeksteen van een product- of servicewebsite. Een statische, one-size-fits-all tabel kan uw prijspunten, maar een dynamische prijstabel [ .. een die updates in real time op basis van gebruikersinteracties .. aanzienlijk verhogen conversiepercentages. Door het toestaan van bezoekers om te schakelen tussen maandelijkse en jaarlijkse facturering, zie de totale kosten met add-ons, of te vergelijken functies interactief, creëer je een transparante en boeiende ervaring. In deze gids, well bouwen een productie-ready dynamische prijstabel met behulp van platte JavaScript en CSS Grid. Geen kaders, geen bibliotheken .. gewoon solide, onderhoudbare code die werkt in moderne browsers.
Het instellen van de HTML-structuur voor een prijsraster
De basis van elke dynamische prijstabel is een schone, semantische HTML-structuur. We beginnen met een container die ons CSS-Grid wordt en vervolgens individuele prijskaarten erin nestelen. Elke kaart moet de naam van het plan, prijs, een lijst van functies en een call-to-action-knop bevatten. Om dynamische updates mogelijk te maken, zullen we een attribuut op elke kaart en de structuur van de prijs container met een klasse kunnen we richten met JavaScript.
<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>
Let op de en om de bereikbaarheid te verbeteren. De klasse op de Pro kaart laat ons de meest populaire optie markeren zonder extra JavaScript.
Bouwen van de CSS-rasterindeling
CSS Grid maakt het eenvoudig om een responsief raster te creëren dat het aantal kolommen aanpast op basis van de viewport. We definiëren de container als een raster, stellen een flexibel aantal kolommen in met en en voegen spatie toe met . Binnen elke kaart gebruiken we CSS Grid intern om de prijs, functies en knop uit te lijnen.
.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;
}
De zorgt ervoor dat de knop altijd onderaan blijft, zelfs als de functielijsten verschillen in lengte. De aanbevolen kaart . .Most Popular
De JavaScript-interactiviteit toevoegen
Nu komt het dynamische deel. We .ll toevoegen een toggle switch die bezoekers laat schakelen tussen maandelijkse en jaarlijkse prijzen. Wanneer de toggle verandert, JavaScript updates van de prijzen voor alle kaarten. We ook een helper om prijzen te formatteren en een soepele overgang voor de numerieke verandering.
<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 voor het schakelen:
.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 dat de update aanstuurt:
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);
});
De object slaat zowel maandelijkse als jaarlijkse tarieven. Jaarlijkse prijzen vertegenwoordigen de kosten per maand bij het jaarlijks betalen van een gemeenschappelijk patroon. De functie itereert over elke kaart, leest haar , en werkt de weergegeven hoeveelheid en periode bij. We werken ook de attribuut bij om de toggle toegankelijk te houden.
Versterking van de overgang
Om de prijsverandering soepel te laten voelen, kunnen we een korte CSS-overgang toevoegen aan de en ] elementen. Echter, aangezien direct verandert, kunnen we een count-up effect simuleren met een klein interval, of gewoon een fade-in gebruiken. Voor een productielocatie werkt een snelle opaciteitsovergang op de prijscontainer goed. Voeg dit toe aan uw CSS:
.price {
transition: opacity 0.2s ease;
}
.updating .price {
opacity: 0;
}
Dan in JavaScript, kort toevoegen en verwijderen van de klasse op elke kaart. Maar voor de meeste gebruiks gevallen, de onmiddellijke update is prima.
Het maken van de tabel Responsive en Toegankelijk
CSS Grid behandelt al responsiviteit, maar zorgt ervoor dat op zeer kleine schermen de kaartenstapel in één kolom. De waarde doet dat automatisch. Voor toegankelijkheid moeten we ervoor zorgen dat de toetstoets-operable is en de status ervan aankondigt. De en hebben we al help schermlezers toegevoegd. Voeg ook toe aan het ouderlabel voor duidelijkheid.
Geef bovendien een zichtbare focusindicator voor gebruikers van toetsenbord. De standaard omtrek werkt, maar je kunt het aanpassen aan uw merk:
.toggle-label input:focus-visible + .toggle-slider {
outline: 2px solid #007bff;
outline-offset: 4px;
}
Test de prijstabel met een schermlezer om te controleren of prijswijzigingen worden aangekondigd. Om dit te verbeteren, kunt u na het bijwerken van de prijs, gebruik maken van een live-regio:
<div aria-live="polite" aria-atomic="true" class="sr-only"></div>
Vervolgens in JavaScript, zet de tekst op iets als
Meer dynamische functies toevoegen
Zodra de kern van het schakelen werkt, kunt u de prijstabel met extra interactiviteit uitbreiden:
Functie aan/uit
Voeg checkboxen toe voor add-ons (bijvoorbeeld extra opslagruimte, teamleden) die de totale prijs bijwerken. Bewaar de basisprijzen en extra kosten in een object. Wanneer een checkbox verandert, bereken het totaal voor elke kaart dienovereenkomstig.
Valutakiezer
Als uw publiek wereldwijd is, voeg een dropdown om te schakelen tussen USD, EUR, GBP, enz. Store conversies en vermenigvuldig de basisprijs. Update de tekst met de juiste valuta-opmaak met behulp van .
Geanimeerde prijsteller
Voor een gepolijst effect, animeer het getal van de oude waarde naar de nieuwe waarde over een paar honderd milliseconden. Bibliotheken als animate.css zijn niet nodig .Een eenvoudige loop werkt. Echter, houd het performant: alleen animeer de zichtbare kaarten.
Spaarbadge
Wanneer jaarlijkse facturering wordt aangeschakeld, toon een
Prestatieoverwegingen
Met slechts een paar prijskaarten, prestaties is geen probleem. Maar als je tientallen plannen (bijvoorbeeld SaaS die plannen genereert uit een database), overwegen deze optimalisaties:
- Gebruik de evenementdelegatie: Een evenementluisteraar aan een ouder-container bevestigen in plaats van elke kaart. Voor het schakelen, dat al gedaan is. Voor checkboxes binnen kaarten, delegeren.
- Cache DOM referenties: Bij initialisatie, slaat u verwijzingen naar de en elementen in een array of Kaart per plansleutel op. Bij het bijwerken hoeft u de DOM niet opnieuw te checken.
- Gebruik voor animaties: Schrijf visuele updates voor de volgende verfcyclus om lay-out thrashing te voorkomen.
- Minimaliseer herflows: Batch DOM wijzigingen bij het bijwerken van meerdere kaarten. In onze functie lezen en schrijven we naar de DOM in een enkele lus ..dat is prima. Als je klassen of inline stijlen toevoegt, overwegen alle waarden eerst te lezen, dan schrijven alle wijzigingen.
Real-World Use Cases en Voorbeelden
Dynamische prijstabellen worden overal gebruikt van abonnementsdiensten zoals Dropbox en Spotify aan hostingproviders zoals DigitalOcean[]. Een gemeenschappelijk patroon is om een maandelijkse / jaarlijkse toggle met een ..Beste Waarde label op de jaarlijkse optie aan te bieden. Sommige bedrijven tonen ook een totale jaarlijkse kosten naast de maandelijkse besparingen. Bijvoorbeeld, een $10/mo-plan met jaarlijkse facturering zou kunnen weergeven . $8/mo . facturated $96 per jaar. Onze structuur ondersteunt dat al met de span.
Een andere variatie is schuifschalen voor hoeveelheid. Een prijstabel voor een SaaS product kan schuifregelaars voor aantal gebruikers of opslag hebben. Als de gebruiker de schuifregelaar beweegt, de prijs updates live. CSS Grid behandelt de lay-out, en JavaScript updates van de prijs waarden. Dit kan worden gebouwd met dezelfde principes: de prijs niveaus opslaan, luisteren naar invoer wijzigingen, en de DOM bijwerken.
Voor een meer geavanceerde aanpak, kunt u prijsgegevens laden uit een JSON-bestand of API, waardoor de tabel echt datagestuurd wordt. Als uw site is gebouwd met een hoofdloze CMS zoals Directus, zouden de prijsgegevens uit een verzameling komen, en uw front-end JavaScript zou het ophalen en het raster dynamisch weergeven. Deze aanpak houdt de prijzen in sync met uw backend.
Testen en browserondersteuning
CSS Grid wordt ondersteund in alle moderne browsers, waaronder Internet Explorer 11 met de prefix
Alternatieve aanpak: CSS-raster met CSS-aangepaste eigenschappen
Een interessante methode om JavaScript voor het aanschuiven van prijzen te vermijden is om CSS Custom Properties te gebruiken en (wanneer browser ondersteuning rijpt). U zou de prijzen als enz., en ze veranderen door een klasse aan te schuiven op het lichaam. Echter, voor echte dynamische logica (bijv., het toevoegen van twee add-ons), JavaScript is nog steeds nodig. De combinatie van zowel CSS voor lay-out en overgangen, JavaScript voor dynamische gegevens .
Conclusie
Het bouwen van een dynamische prijstabel met JavaScript en CSS Grid is zowel haalbaar als breidt uit. Door te beginnen met semantische HTML, het structureren van het raster met CSS Grid, en het toevoegen van eenvoudige JavaScript voor interactiviteit, creëer je een hulpmiddel dat zich kan aanpassen aan complexe prijsmodellen zonder opgeblazen afhankelijkheden. Dezelfde principes . data-gedreven updates, responsieve lay-out, toegankelijke controles .. schaal voor enterprise-level toepassingen. Als een volgende stap, overwegen ]lezen van het MDN CSS Grid documentatie[] voor meer technieken, of verkennen Sara Soueidan toegankelijkheid-eerste togggle switch design[. Voor het verwerken van complexe gegevensbindingen zonder een kader, ] biedt de Vanilla JS Toolkit lichtgewicht helpers.
Nu implementeren deze patronen in uw eigen project. Uw gebruikers zullen de duidelijkheid waarderen, en uw conversiepercentages kunnen u bedanken.