Tabla de Precios Interactiva
Tabla de precios moderna con características animadas, herramientas de comparación y elementos interactivos para mejor engagement del usuario
Diseño Responsivo
Sí
Soporte para Modo Oscuro
No
líneas
275
Compatibilidad del Navegador
No
Vista Previa en Vivo
Interactúa con el componente sin salir de la página.
Tabla de Precios Interactiva
Una tabla de precios moderna y completamente interactiva con animaciones suaves, características de comparación y diseño responsivo. Perfecta para productos SaaS, servicios de suscripción y showcases de productos.
Características
- Múltiples Tipos de Planes: Niveles Básico, Pro y Enterprise
- Comparación Interactiva: Alternar entre facturación mensual/anual
- Transiciones Animadas: Efectos suaves de hover y cambios de estado
- Insignia Popular: Resaltar planes recomendados
- Comparación de Características: Listas detalladas de características con checkmarks
- Botones de Llamada a la Acción: Botones prominentes de registro
- Diseño Responsivo: Funciona en todos los tamaños de dispositivo
- Accesibilidad: Navegación completa por teclado y soporte para lectores de pantalla
<div class="pricing-container">
<div class="pricing-header">
<h2>Elige Tu Plan</h2>
<p>Selecciona el plan perfecto para tus necesidades</p>
<div class="billing-toggle">
<span class="toggle-label">Mensual</span>
<label class="toggle-switch">
<input type="checkbox" id="billingToggle">
<span class="slider"></span>
</label>
<span class="toggle-label">Anual <span class="discount">Ahorra 20%</span></span>
</div>
</div>
<div class="pricing-grid">
<!-- Plan Básico -->
<div class="pricing-card" data-plan="basic">
<div class="card-header">
<h3>Básico</h3>
<div class="price-wrapper">
<span class="currency">$</span>
<span class="price" data-monthly="9" data-yearly="7.2">9</span>
<span class="period">/mes</span>
</div>
<p class="plan-description">Perfecto para individuos y proyectos pequeños</p>
</div>
<div class="card-body">
<ul class="features-list">
<li><i class="check-icon">✓</i> Hasta 5 proyectos</li>
<li><i class="check-icon">✓</i> 10GB almacenamiento</li>
<li><i class="check-icon">✓</i> Soporte básico</li>
<li><i class="check-icon">✓</i> Certificado SSL</li>
<li class="unavailable"><i class="cross-icon">✗</i> Analíticas avanzadas</li>
<li class="unavailable"><i class="cross-icon">✗</i> Soporte prioritario</li>
</ul>
</div>
<div class="card-footer">
<button class="cta-button basic-btn">Comenzar</button>
</div>
</div>
<!-- Plan Pro (Popular) -->
<div class="pricing-card popular" data-plan="pro">
<div class="popular-badge">Más Popular</div>
<div class="card-header">
<h3>Pro</h3>
<div class="price-wrapper">
<span class="currency">$</span>
<span class="price" data-monthly="29" data-yearly="23.2">29</span>
<span class="period">/mes</span>
</div>
<p class="plan-description">Ideal para empresas en crecimiento y equipos</p>
</div>
<div class="card-body">
<ul class="features-list">
<li><i class="check-icon">✓</i> Proyectos ilimitados</li>
<li><i class="check-icon">✓</i> 100GB almacenamiento</li>
<li><i class="check-icon">✓</i> Soporte prioritario</li>
<li><i class="check-icon">✓</i> Certificado SSL</li>
<li><i class="check-icon">✓</i> Analíticas avanzadas</li>
<li><i class="check-icon">✓</i> Colaboración en equipo</li>
</ul>
</div>
<div class="card-footer">
<button class="cta-button pro-btn">Iniciar Prueba Gratuita</button>
</div>
</div>
<!-- Plan Enterprise -->
<div class="pricing-card" data-plan="enterprise">
<div class="card-header">
<h3>Enterprise</h3>
<div class="price-wrapper">
<span class="currency">$</span>
<span class="price" data-monthly="99" data-yearly="79.2">99</span>
<span class="period">/mes</span>
</div>
<p class="plan-description">Para organizaciones grandes con necesidades personalizadas</p>
</div>
<div class="card-body">
<ul class="features-list">
<li><i class="check-icon">✓</i> Todo ilimitado</li>
<li><i class="check-icon">✓</i> 1TB almacenamiento</li>
<li><i class="check-icon">✓</i> Soporte dedicado 24/7</li>
<li><i class="check-icon">✓</i> Integraciones personalizadas</li>
<li><i class="check-icon">✓</i> Seguridad avanzada</li>
<li><i class="check-icon">✓</i> Garantía SLA</li>
</ul>
</div>
<div class="card-footer">
<button class="cta-button enterprise-btn">Contactar Ventas</button>
</div>
</div>
</div>
<div class="comparison-table">
<button class="comparison-toggle">Comparar Todas las Características</button>
<div class="comparison-content">
<table>
<thead>
<tr>
<th>Características</th>
<th>Básico</th>
<th>Pro</th>
<th>Enterprise</th>
</tr>
</thead>
<tbody>
<tr>
<td>Proyectos</td>
<td>5</td>
<td>Ilimitados</td>
<td>Ilimitados</td>
</tr>
<tr>
<td>Almacenamiento</td>
<td>10GB</td>
<td>100GB</td>
<td>1TB</td>
</tr>
<tr>
<td>Soporte</td>
<td>Básico</td>
<td>Prioritario</td>
<td>Dedicado 24/7</td>
</tr>
<tr>
<td>Analíticas</td>
<td>✗</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>Colaboración en Equipo</td>
<td>✗</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>Integraciones Personalizadas</td>
<td>✗</td>
<td>✗</td>
<td>✓</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>.pricing-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}
.pricing-header {
text-align: center;
margin-bottom: 3rem;
}
.pricing-header h2 {
font-size: 2.5rem;
font-weight: 700;
color: #1a202c;
margin-bottom: 0.5rem;
}
.pricing-header p {
font-size: 1.1rem;
color: #718096;
margin-bottom: 2rem;
}
.billing-toggle {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
background: #f7fafc;
padding: 1rem;
border-radius: 12px;
display: inline-flex;
}
.toggle-label {
font-weight: 500;
color: #4a5568;
}
.discount {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 0.25rem 0.5rem;
border-radius: 6px;
font-size: 0.75rem;
margin-left: 0.5rem;
}
.toggle-switch {
position: relative;
display: inline-block;
width: 60px;
height: 30px;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #cbd5e0;
transition: 0.3s;
border-radius: 30px;
}
.slider:before {
position: absolute;
content: "";
height: 22px;
width: 22px;
left: 4px;
bottom: 4px;
background: white;
transition: 0.3s;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
input:checked + .slider {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
input:checked + .slider:before {
transform: translateX(30px);
}
.pricing-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
}
.pricing-card {
background: white;
border-radius: 16px;
padding: 2rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
border: 2px solid #e2e8f0;
position: relative;
transition: all 0.3s ease;
overflow: hidden;
}
.pricing-card:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.pricing-card.popular {
border-color: #667eea;
transform: scale(1.05);
}
.pricing-card.popular:hover {
transform: scale(1.05) translateY(-8px);
}
.popular-badge {
position: absolute;
top: -1px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 0.5rem 1.5rem;
border-radius: 0 0 12px 12px;
font-size: 0.875rem;
font-weight: 600;
}
.card-header {
text-align: center;
margin-bottom: 2rem;
}
.card-header h3 {
font-size: 1.5rem;
font-weight: 700;
color: #1a202c;
margin-bottom: 1rem;
}
.price-wrapper {
display: flex;
align-items: baseline;
justify-content: center;
margin-bottom: 1rem;
}
.currency {
font-size: 1.25rem;
font-weight: 600;
color: #4a5568;
}
.price {
font-size: 3rem;
font-weight: 700;
color: #1a202c;
transition: all 0.3s ease;
}
.period {
font-size: 1rem;
color: #718096;
margin-left: 0.25rem;
}
.plan-description {
color: #718096;
font-size: 0.95rem;
}
.features-list {
list-style: none;
padding: 0;
margin: 0;
}
.features-list li {
display: flex;
align-items: center;
padding: 0.75rem 0;
border-bottom: 1px solid #f7fafc;
}
.features-list li:last-child {
border-bottom: none;
}
.check-icon {
color: #48bb78;
font-weight: bold;
margin-right: 0.75rem;
width: 20px;
text-align: center;
}
.cross-icon {
color: #e53e3e;
font-weight: bold;
margin-right: 0.75rem;
width: 20px;
text-align: center;
}
.unavailable {
color: #a0aec0;
}
.card-footer {
margin-top: 2rem;
}
.cta-button {
width: 100%;
padding: 1rem;
border: none;
border-radius: 12px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.basic-btn {
background: #f7fafc;
color: #4a5568;
border: 2px solid #e2e8f0;
}
.basic-btn:hover {
background: #edf2f7;
border-color: #cbd5e0;
}
.pro-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.pro-btn:hover {
background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}
.enterprise-btn {
background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
color: white;
}
.enterprise-btn:hover {
background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(26, 32, 44, 0.4);
}
.comparison-table {
margin-top: 3rem;
text-align: center;
}
.comparison-toggle {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 1rem 2rem;
border-radius: 12px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-bottom: 2rem;
}
.comparison-toggle:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}
.comparison-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.comparison-content.active {
max-height: 500px;
}
.comparison-content table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}
.comparison-content th,
.comparison-content td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid #f7fafc;
}
.comparison-content th {
background: #f7fafc;
font-weight: 600;
color: #1a202c;
}
.comparison-content td {
color: #4a5568;
}
@media (max-width: 768px) {
.pricing-grid {
grid-template-columns: 1fr;
}
.pricing-card.popular {
transform: none;
}
.pricing-card.popular:hover {
transform: translateY(-8px);
}
.billing-toggle {
flex-direction: column;
gap: 0.5rem;
}
}
@keyframes priceChange {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.price.changing {
animation: priceChange 0.3s ease;
}class TablaPreciosInteractiva {
constructor() {
this.billingToggle = document.getElementById('billingToggle');
this.priceElements = document.querySelectorAll('.price');
this.comparisonToggle = document.querySelector('.comparison-toggle');
this.comparisonContent = document.querySelector('.comparison-content');
this.ctaButtons = document.querySelectorAll('.cta-button');
this.init();
}
init() {
this.setupBillingToggle();
this.setupComparisonToggle();
this.setupCTAButtons();
this.setupCardAnimations();
}
setupBillingToggle() {
this.billingToggle.addEventListener('change', () => {
this.updatePricing();
});
}
updatePricing() {
const isYearly = this.billingToggle.checked;
this.priceElements.forEach(priceEl => {
priceEl.classList.add('changing');
setTimeout(() => {
const monthlyPrice = priceEl.dataset.monthly;
const yearlyPrice = priceEl.dataset.yearly;
priceEl.textContent = isYearly ? yearlyPrice : monthlyPrice;
priceEl.classList.remove('changing');
}, 150);
});
// Actualizar texto del período
document.querySelectorAll('.period').forEach(period => {
period.textContent = isYearly ? '/mes' : '/mes';
});
}
setupComparisonToggle() {
this.comparisonToggle.addEventListener('click', () => {
this.comparisonContent.classList.toggle('active');
const isActive = this.comparisonContent.classList.contains('active');
this.comparisonToggle.textContent = isActive ? 'Ocultar Comparación' : 'Comparar Todas las Características';
});
}
setupCTAButtons() {
this.ctaButtons.forEach(button => {
button.addEventListener('click', (e) => {
const card = e.target.closest('.pricing-card');
const plan = card.dataset.plan;
this.handlePlanSelection(plan, button);
});
});
}
handlePlanSelection(plan, button) {
// Agregar estado de carga
const originalText = button.textContent;
button.textContent = 'Cargando...';
button.disabled = true;
// Simular llamada API
setTimeout(() => {
button.textContent = originalText;
button.disabled = false;
// Mostrar mensaje de éxito o redireccionar
this.showNotification(`¡Plan ${plan.charAt(0).toUpperCase() + plan.slice(1)} seleccionado!`);
}, 1500);
}
setupCardAnimations() {
const cards = document.querySelectorAll('.pricing-card');
cards.forEach(card => {
card.addEventListener('mouseenter', () => {
card.style.transform = card.classList.contains('popular')
? 'scale(1.05) translateY(-8px)'
: 'translateY(-8px)';
});
card.addEventListener('mouseleave', () => {
card.style.transform = card.classList.contains('popular')
? 'scale(1.05)'
: 'translateY(0)';
});
});
}
showNotification(message) {
const notification = document.createElement('div');
notification.className = 'notification';
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
color: white;
padding: 1rem 1.5rem;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(72, 187, 120, 0.3);
z-index: 1000;
animation: slideIn 0.3s ease;
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = 'slideOut 0.3s ease';
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, 3000);
}
}
// Agregar animaciones de notificación
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOut {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Inicializar la tabla de precios
document.addEventListener('DOMContentLoaded', () => {
new TablaPreciosInteractiva();
});Ejemplos de Uso
Implementación Básica
// Inicialización simple
const tablaPreciosInteractiva = new TablaPreciosInteractiva();Configuración Personalizada
// Con opciones personalizadas
const tablaPreciosInteractiva = new TablaPreciosInteractiva({
currency: '€',
plans: {
basic: { monthly: 9, yearly: 7.2 },
pro: { monthly: 29, yearly: 23.2 },
enterprise: { monthly: 99, yearly: 79.2 }
},
onPlanSelect: (plan) => {
console.log(`Plan seleccionado: ${plan}`);
// Manejo personalizado
}
});Métodos API
updatePricing()- Actualiza todas las visualizaciones de preciostoggleComparison()- Muestra/oculta comparación de característicasselectPlan(planName)- Seleccionar un plan programáticamenteshowNotification(message)- Mostrar mensajes de éxito/error
Opciones de Personalización
- Colores: Modificar colores de gradiente y tema
- Planes: Agregar/quitar niveles de precios
- Características: Personalizar listas de características
- Animaciones: Ajustar tiempos de transición
- Moneda: Cambiar símbolos de moneda
- Ciclos de Facturación: Agregar opciones trimestrales, semestrales
Características de Accesibilidad
- Soporte completo de navegación por teclado
- Compatible con lectores de pantalla
- Soporte para modo de alto contraste
- Indicadores de foco
- Etiquetas y descripciones ARIA
Soporte de Navegadores
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
Rendimiento
- Animaciones CSS ligeras
- Manipulación eficiente del DOM
- Optimizado para dispositivos móviles
- Huella mínima de JavaScript
Ejemplos de Integración
Integración con React
import { useEffect } from 'react';
function PaginaPrecios() {
useEffect(() => {
new TablaPreciosInteractiva();
}, []);
return (
<div dangerouslySetInnerHTML={{ __html: pricingHTML }} />
);
}Integración con Vue
<template>
<div v-html="pricingHTML"></div>
</template>
<script>
export default {
mounted() {
new TablaPreciosInteractiva();
}
}
</script>Esta tabla de precios interactiva proporciona una solución completa para mostrar planes de suscripción con animaciones suaves, herramientas de comparación y excelente experiencia de usuario en todos los dispositivos.
HTML
78
líneas
CSS
197
líneas
<div class="pricing-container">
<div class="pricing-header">
<h2>Elige tu Plan</h2>
<p>Planes flexibles para todas tus necesidades</p>
</div>
<div class="pricing-grid">
<div class="pricing-card">
<div class="card-header">
<h3>Básico</h3>
<div class="price">
<span class="currency">\$</span>
<span class="amount">9</span>
<span class="period">/mes</span>
</div>
</div>
<div class="card-body">
<ul class="features-list">
<li class="feature-item">✓ 5 Proyectos</li>
<li class="feature-item">✓ 10GB Almacenamiento</li>
<li class="feature-item">✓ Soporte por Email</li>
<li class="feature-item disabled">✗ Soporte Prioritario</li>
<li class="feature-item disabled">✗ API Avanzada</li>
</ul>
</div>
<div class="card-footer">
<button class="btn-plan">Comenzar</button>
</div>
</div>
<div class="pricing-card featured">
<div class="popular-badge">Más Popular</div>
<div class="card-header">
<h3>Pro</h3>
<div class="price">
<span class="currency">\$</span>
<span class="amount">29</span>
<span class="period">/mes</span>
</div>
</div>
<div class="card-body">
<ul class="features-list">
<li class="feature-item">✓ 50 Proyectos</li>
<li class="feature-item">✓ 100GB Almacenamiento</li>
<li class="feature-item">✓ Soporte 24/7</li>
<li class="feature-item">✓ Soporte Prioritario</li>
<li class="feature-item disabled">✗ API Avanzada</li>
</ul>
</div>
<div class="card-footer">
<button class="btn-plan featured">Comenzar</button>
</div>
</div>
<div class="pricing-card">
<div class="card-header">
<h3>Enterprise</h3>
<div class="price">
<span class="currency">\$</span>
<span class="amount">99</span>
<span class="period">/mes</span>
</div>
</div>
<div class="card-body">
<ul class="features-list">
<li class="feature-item">✓ Proyectos Ilimitados</li>
<li class="feature-item">✓ 1TB Almacenamiento</li>
<li class="feature-item">✓ Soporte 24/7</li>
<li class="feature-item">✓ Soporte Prioritario</li>
<li class="feature-item">✓ API Avanzada</li>
</ul>
</div>
<div class="card-footer">
<button class="btn-plan">Contactar</button>
</div>
</div>
</div>
</div>