Introduction: Pourquoi une table de tarification dynamique compte

Les tables de tarification sont une pierre angulaire de tout site Web de produit ou de service. Une table statique et unique peut présenter vos points de prix, mais une table de tarification dynamique [ – une table qui se met à jour en temps réel en fonction des interactions avec les utilisateurs – peut augmenter de façon significative les taux de conversion. En permettant aux visiteurs de basculer entre la facturation mensuelle et annuelle, de voir le coût total avec des ajouts ou de comparer des fonctionnalités interactivement, vous créez une expérience transparente et engageante.

Configuration de la structure HTML pour une grille de tarification

La base de toute table de tarification dynamique est une structure HTML propre et sémantique. Nous allons commencer par un conteneur qui deviendra notre CSS Grid, puis nicher des cartes de tarification individuelles à l'intérieur. Chaque carte devrait contenir le nom du plan, le prix, une liste de fonctionnalités, et un bouton d'appel à l'action. Pour activer les mises à jour dynamiques, nous allons inclure un attribut sur chaque carte et structurer le conteneur de prix avec une classe que nous pouvons cibler avec 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>

Notez les et pour améliorer l'accessibilité. La classe sur la carte Pro nous permet de mettre en évidence l'option la plus populaire sans JavaScript supplémentaire.

Construire la structure de grille CSS

CSS Grid rend simple la création d'une grille réactive qui ajuste le nombre de colonnes en fonction du port de vue. Nous définissons le conteneur comme une grille, définissons un nombre flexible de colonnes avec et , et ajoutons l'espacement avec . À l'intérieur de chaque carte, nous utilisons CSS Grid en interne pour aligner le prix, les fonctionnalités et le bouton.

.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;
}

Le assure que le bouton reste toujours en bas, même si les listes de fonctionnalités diffèrent en longueur. Le badge de la carte en vedette - - est créé avec un pseudoelement pour éviter un balisage supplémentaire.

Ajout de l'interactivité JavaScript

Maintenant vient la partie dynamique. We ,ll ajouter un basculeur qui permet aux visiteurs de basculer entre le prix mensuel et annuel. Lorsque le basculement change, JavaScript met à jour les prix de toutes les cartes. Nous incluons également un aide au format des prix et une transition en douceur pour le changement numérique.

<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 pour le basculement :

.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 qui permet la mise à jour:

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);
});

Les prix annuels représentent le coût par mois pour le paiement annuel — un modèle commun. La fonction itère sur chaque carte, lit son , et met à jour le montant affiché et la période. Nous mettons également à jour l'attribut pour garder le bascule accessible.

Améliorer la transition

Pour que le changement de prix se fasse sans problème, nous pouvons ajouter une brève transition CSS sur les éléments et . Cependant, puisque change instantanément, nous pouvons simuler un effet de comptage avec un petit intervalle, ou simplement utiliser un fade-in. Pour un site de production, une transition rapide d'opacité sur le conteneur de prix fonctionne bien.

.price {
 transition: opacity 0.2s ease;
}

.updating .price {
 opacity: 0;
}

Puis dans JavaScript, ajoutez et supprimez brièvement la classe sur chaque carte. Mais pour la plupart des cas d'utilisation, la mise à jour instantanée est bonne.

Rendre la table réceptive et accessible

CSS Grid gère déjà la réactivité, mais veille à ce que sur les très petits écrans les cartes s'accumulent dans une seule colonne. La valeur le fait automatiquement. Pour l'accessibilité, nous devons nous assurer que le toggle est compatible avec le clavier et annonce son état. Les et nous avons déjà aidé les lecteurs d'écran.

En outre, fournir un indicateur de focalisation visible pour les utilisateurs de clavier. Le contour par défaut fonctionne, mais vous pouvez le style pour correspondre à votre marque:

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

Testez le tableau de prix avec un lecteur d'écran pour vérifier que les changements de prix sont annoncés. Pour améliorer cela, après la mise à jour du prix, vous pouvez utiliser une région en direct:

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

Puis, en JavaScript, définissez son texte à quelque chose comme -- Prix mis à jour à la facturation annuelle - après chaque bascule. Cet élément écran-lecteur-seulement annoncera le changement sans perturbation visuelle.

Ajout de fonctionnalités plus dynamiques

Une fois que le noyau bascule fonctionne, vous pouvez étendre le tableau de prix avec l'interactivité supplémentaire:

Tombeaux de caractéristiques

Ajouter des cases à cocher pour les add‐ons (p. ex. stockage supplémentaire, membres de l'équipe) qui mettent à jour le prix total. Stockez les prix de base et les coûts supplémentaires dans un objet. Lorsqu'une case change, recalculez le total de chaque carte en conséquence.

Sélecteur de devises

Si votre public est global, ajoutez un menu déroulant pour basculer entre USD, EUR, GBP, etc. Stockez les taux de conversion et multipliez le prix de base. Mettez à jour le texte avec le formatage de la monnaie approprié en utilisant .

Compteur de prix animés

Pour un effet poli, animer le nombre de l'ancienne valeur à la nouvelle valeur sur quelques centaines de millisecondes. Des bibliothèques comme animate.css ne sont pas nécessaires — une simple boucle fonctionne. Cependant, garder performant: seulement animer les cartes visibles.

Insigne d'épargne

Lorsque la facturation annuelle est toggled, montrez un badge --Épargnez 20% de votre badge à côté du prix. Calculez les économies comme et affichez-le dynamiquement. Ajoutez un attribut à chaque carte en HTML et laissez JavaScript la remplir ou le calculer à la volée.

Considérations relatives aux performances

Avec seulement quelques cartes de prix, la performance n'est pas une préoccupation. Mais si vous avez des dizaines de plans (par exemple, SaaS qui génère des plans à partir d'une base de données), considérez ces optimisations:

  • Utilisez la délégation d'événement:[ Joindre un auditeur d'événement à un conteneur parent au lieu de chaque carte. Pour le basculement, cela est déjà fait.
  • Cache DOM references:[ Lors de l'initialisation, entreposez les références aux éléments et dans un tableau ou une carte par clé de plan.
  • Utilisez pour les animations : Planifiez des mises à jour visuelles pour le prochain cycle de peinture afin d'éviter les écrasements de la disposition.
  • Minimisez les reflows: Le lot DOM change lors de la mise à jour de plusieurs cartes. Dans notre fonction , nous lisons et écrivons le DOM en une seule boucle — ce qui est très bien. Si vous ajoutez des classes ou des styles en ligne, envisagez d'abord de lire toutes les valeurs, puis écrivez tous les changements.

Cas et exemples d'utilisations réelles dans le monde

Des tableaux de prix dynamiques sont utilisés partout depuis des services d'abonnement comme Dropbox et [Spotify[ à des fournisseurs d'hébergement comme DigitalOcean[. Un modèle courant est d'offrir une bascule mensuelle/annuelle avec une étiquette -"Meilleure valeur" sur l'option annuelle. Certaines entreprises affichent également une charge annuelle totale à côté de l'épargne mensuelle. Par exemple, un plan de 10 $/mois avec facturation annuelle pourrait afficher -"$8/mo — facturé 96 $ annuellement. Notre structure supporte déjà cela avec la portée .

Une autre variation est la balance coulissante pour la quantité. Un tableau de prix pour un produit SaaS peut avoir des curseurs pour le nombre d'utilisateurs ou de stockage. Lorsque l'utilisateur déplace le curseur, les mises à jour de prix en direct. CSS Grid gère la mise en page, et JavaScript met à jour les valeurs de prix.

Pour une approche plus avancée, vous pouvez charger les données de tarification à partir d'un fichier JSON ou d'une API, ce qui rend la table vraiment axée sur les données. Si votre site est construit avec un CMS sans tête comme Directus, les données de tarification proviendraient d'une collection, et votre front-end JavaScript le récupérerait et rendrait la grille dynamique.

Tests et support du navigateur

Le JavaScript utilisé ici (ES6 ], , les fonctions de flèche, , les modèles littéraux) fonctionne dans Chrome, Firefox, Safari et Edge. Si vous devez soutenir les navigateurs plus anciens, transpile avec Babel ou utiliser et les fonctions traditionnelles. Le est bien supporté dans les lecteurs d'écran modernes, mais vous pouvez également utiliser une case à cocher standard avec une région cachée comme un repli.

Approche alternative : CSS Grid avec les propriétés personnalisées CSS

Une méthode intéressante pour éviter JavaScript pour les prix de basculement est d'utiliser CSS Custom Properties et (lorsqu'un navigateur supporte la maturité). Vous fixeriez les prix comme etc., et les changeriez en basculeant une classe sur le corps. Cependant, pour la vraie logique dynamique (par exemple, ajouter deux add‐ons), JavaScript est toujours nécessaire. La combinaison des deux — CSS pour la mise en page et les transitions, JavaScript pour les données dynamiques — est la plus robuste.

Conclusion

En commençant par le HTML sémantique, en structurant le réseau avec le Grid CSS, et en ajoutant le JavaScript simple pour l'interactivité, vous créez un outil qui peut s'adapter aux modèles de tarification complexes sans dépendances gonflées. Les mêmes principes — mises à jour basées sur les données, mise en page réactive, contrôles accessibles — échelle aux applications de niveau entreprise. Comme une prochaine étape, considérez lire la documentation du Grid CSS MDN pour plus de techniques, ou explorer Sara Soueidan=s accessibility‐first toggle switch design.Pour traiter des fixations de données complexes sans cadre, la Vanilla JS Toolkit offre des aides légères.

Implémentez maintenant ces modèles dans votre propre projet. Vos utilisateurs apprécieront la clarté et vos taux de conversion peuvent vous remercier.