Banner de Cookies Lateral con Efecto Blur
Un elegante banner de consentimiento de cookies estilo barra lateral con sofisticados efectos de desenfoque de fondo, animaciones suaves y diseño glassmorphism moderno para una experiencia de usuario mejorada
Diseño Responsivo
Sí
Soporte para Modo Oscuro
No
líneas
1539
Compatibilidad del Navegador
No
Vista Previa en Vivo
Interactúa con el componente sin salir de la página.
Banner de Cookies Lateral con Efecto Blur
Un sofisticado banner de consentimiento de cookies estilo barra lateral que combina diseño glassmorphism moderno con elegantes efectos de desenfoque de fondo. Este banner se desliza suavemente desde el lateral, creando una experiencia de usuario inmersiva y no intrusiva mientras mantiene total cumplimiento RGPD y estándares de accesibilidad.
Características
- Diseño Glassmorphism: Efecto moderno de cristal esmerilado con desenfoque de fondo
- Diseño Lateral: Panel lateral eficiente en espacio que no obstruye el contenido principal
- Efecto Blur de Fondo: Efecto dinámico de desenfoque de fondo para mayor enfoque
- Animaciones Suaves: Transiciones fluidas de deslizamiento y micro-interacciones
- Divulgación Progresiva: Secciones expandibles para información detallada de cookies
- Cumplimiento RGPD: Gestión completa de consentimiento con controles granulares
- Accesibilidad Primero: Navegación completa por teclado y soporte para lectores de pantalla
- Diseño Responsive: Se adapta perfectamente a todos los tamaños de pantalla y orientaciones
- UI Moderna: Interfaz limpia y profesional con animaciones sutiles
- Optimizado para Rendimiento: Implementación ligera con carga rápida
Vista Previa
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Banner Cookies Lateral Blur</title>
<style>
:root {
--primary-color: #6366f1;
--primary-hover: #4f46e5;
--secondary-color: #8b5cf6;
--success-color: #10b981;
--success-hover: #059669;
--warning-color: #f59e0b;
--danger-color: #ef4444;
--background: #ffffff;
--surface: rgba(255, 255, 255, 0.9);
--surface-hover: rgba(255, 255, 255, 0.95);
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: rgba(255, 255, 255, 0.2);
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
--border-radius: 12px;
--border-radius-lg: 16px;
--border-radius-xl: 20px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
--transition-fast: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
--blur-amount: 20px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--text-primary);
line-height: 1.6;
padding: 2rem;
overflow-x: hidden;
position: relative;
}
.demo-container {
max-width: 1200px;
margin: 0 auto;
text-align: center;
color: white;
position: relative;
z-index: 1;
}
.demo-container h1 {
font-size: 3rem;
font-weight: 800;
margin-bottom: 1rem;
background: linear-gradient(135deg, #ffffff 0%, #f0f0f0 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.demo-container p {
font-size: 1.2rem;
opacity: 0.9;
margin-bottom: 2rem;
}
.demo-btn {
padding: 1rem 2rem;
border: none;
border-radius: var(--border-radius);
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
color: white;
font-family: inherit;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.demo-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
/* Superposición de Desenfoque de Fondo */
.blur-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
backdrop-filter: blur(var(--blur-amount));
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9998;
}
.blur-overlay.active {
opacity: 1;
visibility: visible;
}
/* Banner de Cookies Lateral con Blur */
.sidebar-blur-cookie-banner {
position: fixed;
top: 0;
right: 0;
width: 420px;
max-width: 90vw;
height: 100vh;
background: var(--surface);
backdrop-filter: blur(var(--blur-amount));
border-left: 1px solid var(--border-color);
transform: translateX(100%);
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9999;
display: flex;
flex-direction: column;
box-shadow: var(--shadow-xl);
overflow: hidden;
}
.sidebar-blur-cookie-banner.show {
transform: translateX(0);
}
.banner-header {
padding: 2rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
border-bottom: 1px solid var(--border-color);
position: relative;
}
.close-button {
position: absolute;
top: 1.5rem;
right: 1.5rem;
width: 40px;
height: 40px;
border: none;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
transition: var(--transition-fast);
font-size: 1.5rem;
border: 1px solid var(--border-color);
}
.close-button:hover {
background: rgba(255, 255, 255, 1);
color: var(--text-primary);
transform: scale(1.1);
box-shadow: var(--shadow-md);
}
.banner-title {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1rem;
}
.banner-icon {
width: 48px;
height: 48px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
border-radius: var(--border-radius);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: white;
animation: float 3s ease-in-out infinite;
box-shadow: var(--shadow-md);
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-5px);
}
}
.title-text {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
}
.banner-description {
color: var(--text-secondary);
font-size: 1rem;
line-height: 1.6;
}
/* Área de Contenido */
.banner-content {
flex: 1;
overflow-y: auto;
padding: 0;
scrollbar-width: thin;
scrollbar-color: rgba(99, 102, 241, 0.3) transparent;
}
.banner-content::-webkit-scrollbar {
width: 6px;
}
.banner-content::-webkit-scrollbar-track {
background: transparent;
}
.banner-content::-webkit-scrollbar-thumb {
background: rgba(99, 102, 241, 0.3);
border-radius: 3px;
}
.banner-content::-webkit-scrollbar-thumb:hover {
background: rgba(99, 102, 241, 0.5);
}
/* Categorías de Cookies */
.cookie-section {
padding: 1.5rem 2rem;
border-bottom: 1px solid var(--border-color);
}
.section-title {
font-size: 1.1rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.section-icon {
width: 20px;
height: 20px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
}
.cookie-category {
margin-bottom: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
background: rgba(255, 255, 255, 0.8);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-info {
flex: 1;
}
.category-title {
font-weight: 600;
font-size: 1rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.category-count {
font-size: 0.8rem;
color: var(--text-muted);
background: rgba(255, 255, 255, 0.8);
padding: 0.25rem 0.5rem;
border-radius: 12px;
display: inline-block;
}
.category-description {
font-size: 0.9rem;
color: var(--text-secondary);
line-height: 1.5;
margin-bottom: 0.75rem;
}
/* Interruptor Toggle */
.toggle-switch {
position: relative;
width: 56px;
height: 32px;
background: rgba(107, 114, 128, 0.3);
border-radius: 16px;
cursor: pointer;
transition: var(--transition);
flex-shrink: 0;
border: 1px solid var(--border-color);
backdrop-filter: blur(10px);
}
.toggle-switch.active {
background: linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%);
}
.toggle-switch.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.toggle-switch::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 26px;
height: 26px;
background: white;
border-radius: 50%;
transition: var(--transition);
box-shadow: var(--shadow-sm);
}
.toggle-switch.active::before {
transform: translateX(24px);
}
.toggle-switch:hover:not(.disabled) {
transform: scale(1.05);
}
/* Detalles Expandibles */
.expandable-section {
margin-top: 0.75rem;
}
.expand-toggle {
display: flex;
align-items: center;
gap: 0.5rem;
background: none;
border: none;
color: var(--primary-color);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: var(--transition-fast);
padding: 0.5rem;
border-radius: var(--border-radius);
width: 100%;
justify-content: flex-start;
}
.expand-toggle:hover {
background: rgba(99, 102, 241, 0.1);
}
.expand-icon {
transition: transform 0.3s ease;
}
.expand-toggle.expanded .expand-icon {
transform: rotate(180deg);
}
.expandable-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.expandable-content.expanded {
max-height: 300px;
}
.cookie-details {
padding: 1rem 0;
}
.cookie-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: var(--border-radius);
margin-bottom: 0.5rem;
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-item:hover {
background: rgba(255, 255, 255, 0.8);
}
.cookie-info {
flex: 1;
}
.cookie-name {
font-weight: 600;
font-size: 0.9rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.cookie-purpose {
font-size: 0.8rem;
color: var(--text-secondary);
line-height: 1.4;
}
.cookie-toggle {
width: 44px;
height: 24px;
background: rgba(107, 114, 128, 0.3);
border-radius: 12px;
position: relative;
cursor: pointer;
transition: var(--transition);
border: 1px solid var(--border-color);
}
.cookie-toggle.active {
background: var(--primary-color);
}
.cookie-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 18px;
height: 18px;
background: white;
border-radius: 50%;
transition: var(--transition);
}
.cookie-toggle.active::before {
transform: translateX(20px);
}
/* Botones de Acción */
.banner-actions {
padding: 2rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
border-top: 1px solid var(--border-color);
display: flex;
flex-direction: column;
gap: 1rem;
}
.action-button {
width: 100%;
padding: 1rem;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
text-transform: uppercase;
letter-spacing: 0.5px;
backdrop-filter: blur(10px);
border: 1px solid var(--border-color);
}
.action-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
.action-button:hover::before {
left: 100%;
}
.btn-accept {
background: linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%);
color: white;
box-shadow: var(--shadow-md);
}
.btn-accept:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-customize {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
color: white;
box-shadow: var(--shadow-md);
}
.btn-customize:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-reject {
background: rgba(239, 68, 68, 0.1);
color: var(--danger-color);
border: 1px solid rgba(239, 68, 68, 0.3);
}
.btn-reject:hover {
background: rgba(239, 68, 68, 0.2);
transform: translateY(-2px);
}
/* Panel de Estadísticas */
.stats-panel {
padding: 1.5rem 2rem;
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%);
border-bottom: 1px solid var(--border-color);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.stat-item {
text-align: center;
padding: 1rem;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
}
.stat-number {
font-size: 1.5rem;
font-weight: 800;
color: var(--primary-color);
margin-bottom: 0.25rem;
}
.stat-label {
font-size: 0.8rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Estados de Carga */
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: currentColor;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Animación de Éxito */
.success-checkmark {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
stroke-width: 2;
stroke: currentColor;
stroke-miterlimit: 10;
box-shadow: inset 0px 0px 0px currentColor;
animation: fill 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;
}
.checkmark-circle {
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: currentColor;
fill: none;
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
}
.checkmark-check {
transform-origin: 50% 50%;
stroke-dasharray: 48;
stroke-dashoffset: 48;
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
}
@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}
@keyframes scale {
0%, 100% {
transform: none;
}
50% {
transform: scale3d(1.1, 1.1, 1);
}
}
@keyframes fill {
100% {
box-shadow: inset 0px 0px 0px 30px currentColor;
}
}
/* Diseño Responsive */
@media (max-width: 768px) {
.sidebar-blur-cookie-banner {
width: 100%;
max-width: none;
border-left: none;
border-top: 1px solid var(--border-color);
}
.banner-header {
padding: 1.5rem;
}
.cookie-section {
padding: 1rem 1.5rem;
}
.banner-actions {
padding: 1.5rem;
}
.stats-grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-header {
padding: 1rem;
}
.cookie-section {
padding: 1rem;
}
.banner-actions {
padding: 1rem;
}
}
/* Variantes de Animación */
.slide-in-right {
animation: slideInRight 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.fade-in-up {
animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes fadeInUp {
from {
transform: translateY(30px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
/* Efectos Glassmorphism */
.glass-effect {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
}
.glass-effect-strong {
background: rgba(255, 255, 255, 0.4);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Diseño Lateral Blur</h1>
<p>Experimenta la elegancia del glassmorphism con sofisticados efectos de desenfoque y animaciones suaves de barra lateral</p>
<button class="demo-btn" onclick="mostrarBannerCookies()">Mostrar Banner de Cookies</button>
</div>
<!-- Superposición de Desenfoque -->
<div id="blurOverlay" class="blur-overlay"></div>
<!-- Banner de Cookies Lateral con Blur -->
<div id="sidebarBlurCookieBanner" class="sidebar-blur-cookie-banner">
<button class="close-button" onclick="cerrarBanner()" aria-label="Cerrar banner">×</button>
<div class="banner-header">
<div class="banner-title">
<div class="banner-icon">🍪</div>
<div class="title-text">Preferencias de Cookies</div>
</div>
<div class="banner-description">
Utilizamos cookies para mejorar tu experiencia de navegación y proporcionar contenido personalizado. Elige tus preferencias a continuación.
</div>
</div>
<div class="stats-panel">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-number">4</div>
<div class="stat-label">Categorías</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">Tipos de Cookies</div>
</div>
</div>
</div>
<div class="banner-content">
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">🔒</div>
Cookies Esenciales
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Estrictamente Necesarias <span class="category-count">Siempre Activas</span></div>
</div>
<div class="toggle-switch active disabled"></div>
</div>
<div class="category-description">
Estas cookies son esenciales para el funcionamiento del sitio web y no se pueden desactivar.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="essential-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="essential-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Cookie de Sesión</div>
<div class="cookie-purpose">Mantiene tu sesión mientras navegas</div>
</div>
<div class="cookie-toggle active"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Token de Seguridad</div>
<div class="cookie-purpose">Protege contra ataques de falsificación de solicitudes</div>
</div>
<div class="cookie-toggle active"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">📊</div>
Cookies de Análisis
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Análisis de Rendimiento <span class="category-count">3 cookies</span></div>
</div>
<div class="toggle-switch" data-category="analytics"></div>
</div>
<div class="category-description">
Nos ayudan a entender cómo los visitantes interactúan con nuestro sitio web recopilando información de forma anónima.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="analytics-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="analytics-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Google Analytics</div>
<div class="cookie-purpose">Rastrea el uso del sitio web y métricas de rendimiento</div>
</div>
<div class="cookie-toggle" data-cookie="ga"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Hotjar</div>
<div class="cookie-purpose">Registra interacciones de usuarios para mejoras de UX</div>
</div>
<div class="cookie-toggle" data-cookie="hotjar"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">🎯</div>
Cookies de Marketing
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Publicidad y Marketing <span class="category-count">5 cookies</span></div>
</div>
<div class="toggle-switch" data-category="marketing"></div>
</div>
<div class="category-description">
Se utilizan para ofrecer anuncios más relevantes basados en tu comportamiento de navegación.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="marketing-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="marketing-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Facebook Pixel</div>
<div class="cookie-purpose">Rastrea conversiones y construye audiencias</div>
</div>
<div class="cookie-toggle" data-cookie="facebook"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Google Ads</div>
<div class="cookie-purpose">Habilita remarketing y personalización de anuncios</div>
</div>
<div class="cookie-toggle" data-cookie="google-ads"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">⚙️</div>
Cookies Funcionales
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Funcionalidad Mejorada <span class="category-count">2 cookies</span></div>
</div>
<div class="toggle-switch" data-category="functional"></div>
</div>
<div class="category-description">
Habilitan funcionalidad mejorada y personalización, como videos y chats en vivo.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="functional-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="functional-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Preferencia de Idioma</div>
<div class="cookie-purpose">Recuerda tu idioma seleccionado</div>
</div>
<div class="cookie-toggle" data-cookie="language"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Preferencia de Tema</div>
<div class="cookie-purpose">Guarda tu preferencia de modo oscuro/claro</div>
</div>
<div class="cookie-toggle" data-cookie="theme"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="banner-actions">
<button class="action-button btn-accept" onclick="aceptarTodasCookies()">Aceptar Todas las Cookies</button>
<button class="action-button btn-customize" onclick="guardarConfiguracionPersonalizada()">Guardar Mis Preferencias</button>
<button class="action-button btn-reject" onclick="rechazarCookiesOpcionales()">Rechazar Opcionales</button>
</div>
</div>
<script>
class BannerCookiesLateralBlur {
constructor(opciones = {}) {
this.opciones = {
mostrarAutomaticamente: true,
retrasoMostrar: 1500,
claveAlmacenamiento: 'sidebar_blur_cookie_consent',
diasExpiracion: 365,
habilitarAnimaciones: true,
cantidadBlur: '20px',
alAceptar: null,
alRechazar: null,
alGuardar: null,
alCerrar: null,
...opciones
};
this.banner = document.getElementById('sidebarBlurCookieBanner');
this.overlay = document.getElementById('blurOverlay');
this.consentimiento = this.obtenerConsentimientoAlmacenado();
this.esVisible = false;
this.inicializar();
}
inicializar() {
if (this.opciones.mostrarAutomaticamente && !this.consentimiento) {
setTimeout(() => this.mostrar(), this.opciones.retrasoMostrar);
}
this.configurarEventListeners();
this.cargarConfiguracion();
this.configurarCantidadBlur();
}
configurarEventListeners() {
// Interruptores toggle
document.querySelectorAll('.toggle-switch:not(.disabled)').forEach(toggle => {
toggle.addEventListener('click', () => {
this.alternarInterruptor(toggle);
});
});
// Toggles de cookies
document.querySelectorAll('.cookie-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
this.alternarInterruptorCookie(toggle);
});
});
// Secciones expandibles
document.querySelectorAll('.expand-toggle').forEach(button => {
button.addEventListener('click', () => {
this.alternarSeccionExpandible(button);
});
});
// Navegación por teclado
document.addEventListener('keydown', (e) => {
if (this.esVisible) {
this.manejarNavegacionTeclado(e);
}
});
// Clic en overlay para cerrar
this.overlay.addEventListener('click', () => {
this.cerrar();
});
// Efectos hover de botones
document.querySelectorAll('.action-button').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.crearRipple(btn);
});
});
}
configurarCantidadBlur() {
document.documentElement.style.setProperty('--blur-amount', this.opciones.cantidadBlur);
}
alternarInterruptor(toggle) {
if (toggle.classList.contains('disabled')) return;
toggle.classList.toggle('active');
if (this.opciones.habilitarAnimaciones) {
this.animarToggle(toggle);
}
// Actualizar toggles de cookies relacionados
const categoria = toggle.dataset.category;
if (categoria) {
this.actualizarTogglesCategorias(categoria, toggle.classList.contains('active'));
}
}
alternarInterruptorCookie(toggle) {
toggle.classList.toggle('active');
if (this.opciones.habilitarAnimaciones) {
this.animarToggle(toggle);
}
// Actualizar categoría padre si es necesario
this.actualizarEstadoCategoriasPadre();
}
actualizarTogglesCategorias(categoria, habilitado) {
const cookieToggles = document.querySelectorAll(`[data-cookie*="${categoria}"]`);
cookieToggles.forEach(toggle => {
if (habilitado) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
});
}
actualizarEstadoCategoriasPadre() {
const categorias = ['analytics', 'marketing', 'functional'];
categorias.forEach(categoria => {
const categoryToggle = document.querySelector(`[data-category="${categoria}"]`);
const cookieToggles = document.querySelectorAll(`[data-cookie*="${categoria}"]`);
if (categoryToggle && cookieToggles.length > 0) {
const todosHabilitados = Array.from(cookieToggles).every(toggle =>
toggle.classList.contains('active'));
if (todosHabilitados) {
categoryToggle.classList.add('active');
} else {
categoryToggle.classList.remove('active');
}
}
});
}
alternarSeccionExpandible(button) {
const targetId = button.dataset.target;
const content = document.getElementById(targetId);
if (content) {
const estaExpandido = content.classList.contains('expanded');
if (estaExpandido) {
content.classList.remove('expanded');
button.classList.remove('expanded');
} else {
content.classList.add('expanded');
button.classList.add('expanded');
if (this.opciones.habilitarAnimaciones) {
this.animarContenidoExpandible(content);
}
}
}
}
animarContenidoExpandible(content) {
const items = content.querySelectorAll('.cookie-item');
items.forEach((item, index) => {
item.style.opacity = '0';
item.style.transform = 'translateY(10px)';
setTimeout(() => {
item.style.transition = 'all 0.3s ease';
item.style.opacity = '1';
item.style.transform = 'translateY(0)';
}, index * 50);
});
}
animarToggle(toggle) {
toggle.style.transform = 'scale(0.95)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
// Agregar efecto de pulso
const color = toggle.classList.contains('active') ?
'rgba(16, 185, 129, 0.3)' : 'rgba(107, 114, 128, 0.3)';
toggle.style.boxShadow = `0 0 0 8px ${color}`;
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
manejarNavegacionTeclado(e) {
switch (e.key) {
case 'Escape':
this.cerrar();
break;
case 'Tab':
// Dejar que el navegador maneje la navegación por tab
break;
}
}
crearRipple(button) {
if (!this.opciones.habilitarAnimaciones) return;
const ripple = document.createElement('span');
const rect = button.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = '50%';
ripple.style.top = '50%';
ripple.style.transform = 'translate(-50%, -50%) scale(0)';
ripple.style.position = 'absolute';
ripple.style.borderRadius = '50%';
ripple.style.background = 'rgba(255, 255, 255, 0.3)';
ripple.style.pointerEvents = 'none';
ripple.style.animation = 'ripple 0.6s ease-out';
button.style.position = 'relative';
button.style.overflow = 'hidden';
button.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
}
mostrar() {
this.banner.classList.add('show');
this.overlay.classList.add('active');
this.esVisible = true;
if (this.opciones.habilitarAnimaciones) {
this.animarEntrada();
}
}
ocultar() {
this.banner.classList.remove('show');
this.overlay.classList.remove('active');
this.esVisible = false;
}
cerrar() {
this.ocultar();
if (this.opciones.alCerrar) {
this.opciones.alCerrar();
}
}
animarEntrada() {
const sections = this.banner.querySelectorAll('.cookie-section');
sections.forEach((section, index) => {
section.style.opacity = '0';
section.style.transform = 'translateX(30px)';
setTimeout(() => {
section.style.transition = 'all 0.5s cubic-bezier(0.4, 0, 0.2, 1)';
section.style.opacity = '1';
section.style.transform = 'translateX(0)';
}, index * 100);
});
}
aceptarTodasCookies() {
const consentimiento = {
esencial: true,
analytics: true,
marketing: true,
funcional: true,
timestamp: Date.now()
};
this.guardarConsentimiento(consentimiento);
this.mostrarAnimacionExito();
setTimeout(() => {
this.ocultar();
}, 1500);
if (this.opciones.alAceptar) {
this.opciones.alAceptar(consentimiento);
}
}
rechazarCookiesOpcionales() {
const consentimiento = {
esencial: true,
analytics: false,
marketing: false,
funcional: false,
timestamp: Date.now()
};
this.guardarConsentimiento(consentimiento);
this.ocultar();
if (this.opciones.alRechazar) {
this.opciones.alRechazar(consentimiento);
}
}
guardarConfiguracionPersonalizada() {
const consentimiento = { timestamp: Date.now() };
// Obtener estados de categorías
consentimiento.esencial = true; // Siempre verdadero
consentimiento.analytics = document.querySelector('[data-category="analytics"]')?.classList.contains('active') || false;
consentimiento.marketing = document.querySelector('[data-category="marketing"]')?.classList.contains('active') || false;
consentimiento.funcional = document.querySelector('[data-category="functional"]')?.classList.contains('active') || false;
// Obtener estados de cookies individuales
const estadosCookies = {};
document.querySelectorAll('[data-cookie]').forEach(toggle => {
const cookie = toggle.dataset.cookie;
estadosCookies[cookie] = toggle.classList.contains('active');
});
consentimiento.cookies = estadosCookies;
this.guardarConsentimiento(consentimiento);
this.mostrarAnimacionExito();
setTimeout(() => {
this.ocultar();
}, 1500);
if (this.opciones.alGuardar) {
this.opciones.alGuardar(consentimiento);
}
}
mostrarAnimacionExito() {
if (!this.opciones.habilitarAnimaciones) return;
const customizeBtn = this.banner.querySelector('.btn-customize');
if (customizeBtn) {
customizeBtn.innerHTML = `
<svg class="success-checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<circle class="checkmark-circle" cx="26" cy="26" r="25" fill="none"/>
<path class="checkmark-check" fill="none" d="m14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
Preferencias Guardadas
`;
customizeBtn.style.background = 'linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%)';
}
}
cargarConfiguracion() {
if (this.consentimiento) {
// Cargar estados de categorías
Object.entries(this.consentimiento).forEach(([key, value]) => {
if (typeof value === 'boolean') {
const toggle = document.querySelector(`[data-category="${key}"]`);
if (toggle && !toggle.classList.contains('disabled')) {
if (value) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
}
});
// Cargar estados de cookies individuales
if (this.consentimiento.cookies) {
Object.entries(this.consentimiento.cookies).forEach(([cookie, habilitado]) => {
const toggle = document.querySelector(`[data-cookie="${cookie}"]`);
if (toggle) {
if (habilitado) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
}
}
guardarConsentimiento(consentimiento) {
const fechaExpiracion = new Date();
fechaExpiracion.setDate(fechaExpiracion.getDate() + this.opciones.diasExpiracion);
const datosConsentimiento = {
...consentimiento,
expiracion: fechaExpiracion.getTime()
};
localStorage.setItem(this.opciones.claveAlmacenamiento, JSON.stringify(datosConsentimiento));
this.consentimiento = consentimiento;
}
obtenerConsentimientoAlmacenado() {
try {
const almacenado = localStorage.getItem(this.opciones.claveAlmacenamiento);
if (almacenado) {
const datos = JSON.parse(almacenado);
if (datos.expiracion && Date.now() < datos.expiracion) {
return datos;
} else {
localStorage.removeItem(this.opciones.claveAlmacenamiento);
}
}
} catch (e) {
console.error('Error al leer consentimiento de cookies:', e);
}
return null;
}
reiniciar() {
localStorage.removeItem(this.opciones.claveAlmacenamiento);
this.consentimiento = null;
this.mostrar();
}
obtenerConsentimiento() {
return this.consentimiento;
}
establecerCantidadBlur(cantidad) {
this.opciones.cantidadBlur = cantidad;
this.configurarCantidadBlur();
}
habilitarAnimaciones(habilitado) {
this.opciones.habilitarAnimaciones = habilitado;
}
actualizarTema(tema) {
const temas = {
claro: {
'--background': '#ffffff',
'--surface': 'rgba(255, 255, 255, 0.9)',
'--text-primary': '#1f2937',
'--text-secondary': '#6b7280'
},
oscuro: {
'--background': '#1f2937',
'--surface': 'rgba(31, 41, 55, 0.9)',
'--text-primary': '#f9fafb',
'--text-secondary': '#d1d5db'
}
};
if (temas[tema]) {
Object.entries(temas[tema]).forEach(([propiedad, valor]) => {
document.documentElement.style.setProperty(propiedad, valor);
});
}
}
}
// Agregar CSS para animación ripple
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Inicializar el banner
const bannerCookies = new BannerCookiesLateralBlur({
cantidadBlur: '20px',
habilitarAnimaciones: true,
alAceptar: (consentimiento) => {
console.log('Cookies aceptadas:', consentimiento);
// Inicializar scripts de analytics, marketing, etc.
},
alRechazar: (consentimiento) => {
console.log('Cookies opcionales rechazadas:', consentimiento);
// Cargar solo scripts esenciales
},
alGuardar: (consentimiento) => {
console.log('Configuración personalizada guardada:', consentimiento);
// Cargar scripts basados en preferencias del usuario
},
alCerrar: () => {
console.log('Banner cerrado sin acción');
}
});
// Funciones globales para demo
function mostrarBannerCookies() {
bannerCookies.reiniciar();
}
function cerrarBanner() {
bannerCookies.cerrar();
}
function aceptarTodasCookies() {
bannerCookies.aceptarTodasCookies();
}
function rechazarCookiesOpcionales() {
bannerCookies.rechazarCookiesOpcionales();
}
function guardarConfiguracionPersonalizada() {
bannerCookies.guardarConfiguracionPersonalizada();
}
</script>
</body>
</html>Cómo Usar
Instalación Básica
<!-- Incluir el CSS -->
<link rel="stylesheet" href="ruta/al/banner-cookies-lateral-blur.css">
<!-- Incluir la estructura HTML -->
<div id="blurOverlay" class="blur-overlay"></div>
<div id="sidebarBlurCookieBanner" class="sidebar-blur-cookie-banner">
<!-- Contenido del banner aquí -->
</div>
<!-- Incluir el JavaScript -->
<script src="ruta/al/banner-cookies-lateral-blur.js"></script>Inicialización con JavaScript
// Inicialización básica
const bannerCookies = new BannerCookiesLateralBlur();
// Inicialización con opciones personalizadas
const bannerCookies = new BannerCookiesLateralBlur({
mostrarAutomaticamente: true,
retrasoMostrar: 2000,
cantidadBlur: '25px',
habilitarAnimaciones: true,
diasExpiracion: 365,
alAceptar: (consentimiento) => {
console.log('Cookies aceptadas:', consentimiento);
// Inicializar Google Analytics, Facebook Pixel, etc.
if (consentimiento.analytics) {
gtag('config', 'GA_MEASUREMENT_ID');
}
if (consentimiento.marketing) {
fbq('init', 'FACEBOOK_PIXEL_ID');
}
},
alRechazar: (consentimiento) => {
console.log('Cookies opcionales rechazadas');
// Cargar solo scripts esenciales
},
alGuardar: (consentimiento) => {
console.log('Configuración guardada:', consentimiento);
// Cargar scripts basados en preferencias
}
});Personalización de Temas
Variables CSS Personalizables
:root {
/* Colores Principales */
--primary-color: #6366f1;
--primary-hover: #4f46e5;
--secondary-color: #8b5cf6;
--success-color: #10b981;
--warning-color: #f59e0b;
--danger-color: #ef4444;
/* Superficies y Fondos */
--background: #ffffff;
--surface: rgba(255, 255, 255, 0.9);
--surface-hover: rgba(255, 255, 255, 0.95);
/* Texto */
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
/* Efectos */
--blur-amount: 20px;
--border-radius: 12px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
/* Sombras */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}Tema Oscuro
[data-theme="dark"] {
--background: #1f2937;
--surface: rgba(31, 41, 55, 0.9);
--surface-hover: rgba(31, 41, 55, 0.95);
--text-primary: #f9fafb;
--text-secondary: #d1d5db;
--text-muted: #9ca3af;
--border-color: rgba(255, 255, 255, 0.1);
}Métodos de API
Métodos Principales
// Mostrar el banner
bannerCookies.mostrar();
// Ocultar el banner
bannerCookies.ocultar();
// Cerrar el banner
bannerCookies.cerrar();
// Aceptar todas las cookies
bannerCookies.aceptarTodasCookies();
// Rechazar cookies opcionales
bannerCookies.rechazarCookiesOpcionales();
// Guardar configuración personalizada
bannerCookies.guardarConfiguracionPersonalizada();
// Reiniciar el banner (borrar consentimiento guardado)
bannerCookies.reiniciar();
// Obtener consentimiento actual
const consentimiento = bannerCookies.obtenerConsentimiento();
// Establecer cantidad de blur
bannerCookies.establecerCantidadBlur('30px');
// Habilitar/deshabilitar animaciones
bannerCookies.habilitarAnimaciones(false);
// Actualizar tema
bannerCookies.actualizarTema('oscuro');Eventos y Callbacks
const bannerCookies = new BannerCookiesLateralBlur({
alAceptar: (consentimiento) => {
// Se ejecuta cuando el usuario acepta todas las cookies
console.log('Consentimiento otorgado:', consentimiento);
// Inicializar servicios basados en el consentimiento
if (consentimiento.analytics) {
inicializarAnalytics();
}
if (consentimiento.marketing) {
inicializarMarketing();
}
},
alRechazar: (consentimiento) => {
// Se ejecuta cuando el usuario rechaza cookies opcionales
console.log('Cookies opcionales rechazadas');
// Cargar solo funcionalidad esencial
cargarSoloEsencial();
},
alGuardar: (consentimiento) => {
// Se ejecuta cuando el usuario guarda configuración personalizada
console.log('Configuración personalizada:', consentimiento);
// Cargar servicios basados en preferencias específicas
cargarServiciosPersonalizados(consentimiento);
},
alCerrar: () => {
// Se ejecuta cuando el banner se cierra sin acción
console.log('Banner cerrado sin consentimiento');
// Manejar cierre sin decisión
manejarCierreSinDecision();
}
});Opciones de Configuración
Configuración Completa
const opciones = {
// Comportamiento
mostrarAutomaticamente: true, // Mostrar automáticamente al cargar
retrasoMostrar: 1500, // Retraso antes de mostrar (ms)
// Almacenamiento
claveAlmacenamiento: 'sidebar_blur_cookie_consent',
diasExpiracion: 365, // Días antes de que expire el consentimiento
// Apariencia
cantidadBlur: '20px', // Cantidad de desenfoque de fondo
habilitarAnimaciones: true, // Habilitar animaciones y transiciones
// Callbacks
alAceptar: null, // Función a ejecutar al aceptar
alRechazar: null, // Función a ejecutar al rechazar
alGuardar: null, // Función a ejecutar al guardar
alCerrar: null // Función a ejecutar al cerrar
};
const bannerCookies = new BannerCookiesLateralBlur(opciones);Configuración de Cookies Personalizadas
// Agregar categorías de cookies personalizadas
const categoriasPersonalizadas = {
social: {
nombre: 'Redes Sociales',
descripcion: 'Cookies para integración con redes sociales',
cookies: ['facebook_connect', 'twitter_widget', 'linkedin_insight']
},
personalizacion: {
nombre: 'Personalización',
descripcion: 'Cookies para personalizar tu experiencia',
cookies: ['user_preferences', 'theme_selection', 'language_choice']
}
};
// Configurar el banner con categorías personalizadas
bannerCookies.configurarCategorias(categoriasPersonalizadas);Soporte de Navegadores
Navegadores Compatibles
- Chrome: 60+
- Firefox: 55+
- Safari: 12+
- Edge: 79+
- Opera: 47+
- iOS Safari: 12+
- Android Chrome: 60+
Características Modernas Utilizadas
- CSS Grid y Flexbox
- CSS Custom Properties (Variables)
- Backdrop Filter (con fallbacks)
- ES6+ JavaScript
- Local Storage API
- Intersection Observer (opcional)
Fallbacks para Navegadores Antiguos
/* Fallback para backdrop-filter */
.sidebar-blur-cookie-banner {
background: rgba(255, 255, 255, 0.95);
}
@supports (backdrop-filter: blur(20px)) {
.sidebar-blur-cookie-banner {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(20px);
}
}Accesibilidad
Características de Accesibilidad
- Navegación por Teclado: Soporte completo para navegación con Tab
- Lectores de Pantalla: Etiquetas ARIA y estructura semántica
- Alto Contraste: Cumple con WCAG 2.1 AA
- Tamaños de Toque: Botones de al menos 44px para dispositivos táctiles
- Indicadores de Foco: Indicadores visuales claros para elementos enfocados
Atributos ARIA
<div class="sidebar-blur-cookie-banner"
role="dialog"
aria-labelledby="banner-title"
aria-describedby="banner-description">
<button class="close-button"
aria-label="Cerrar banner de cookies">
×
</button>
<div class="toggle-switch"
role="switch"
aria-checked="false"
aria-labelledby="category-title">
</div>
</div>Cumplimiento RGPD
Características de Cumplimiento
- Consentimiento Granular: Control individual sobre categorías de cookies
- Consentimiento Explícito: No hay cookies pre-seleccionadas (excepto esenciales)
- Fácil Retiro: Opción clara para retirar el consentimiento
- Información Transparente: Descripciones claras del propósito de cada cookie
- Registro de Consentimiento: Almacenamiento con timestamp del consentimiento
Gestión de Consentimiento
// Verificar consentimiento para una categoría específica
function verificarConsentimiento(categoria) {
const consentimiento = bannerCookies.obtenerConsentimiento();
return consentimiento && consentimiento[categoria] === true;
}
// Cargar scripts condicionalmente
if (verificarConsentimiento('analytics')) {
// Cargar Google Analytics
gtag('config', 'GA_MEASUREMENT_ID');
}
if (verificarConsentimiento('marketing')) {
// Cargar Facebook Pixel
fbq('init', 'FACEBOOK_PIXEL_ID');
}Rendimiento
Optimizaciones de Rendimiento
- Carga Diferida: Scripts de terceros se cargan solo después del consentimiento
- CSS Optimizado: Uso eficiente de propiedades CSS para animaciones
- JavaScript Ligero: Implementación vanilla sin dependencias
- Almacenamiento Local: Evita verificaciones de servidor repetidas
- Animaciones GPU: Uso de transform y opacity para animaciones suaves
Métricas de Rendimiento
- Tamaño del Bundle: ~15KB (CSS + JS minificado)
- Tiempo de Inicialización: <50ms
- Memoria Utilizada: <2MB
- Impacto en FCP: <100ms
Optimización de Carga
<!-- Carga crítica -->
<link rel="preload" href="banner-cookies-lateral-blur.css" as="style">
<link rel="stylesheet" href="banner-cookies-lateral-blur.css">
<!-- Carga diferida del JavaScript -->
<script>
window.addEventListener('load', function() {
const script = document.createElement('script');
script.src = 'banner-cookies-lateral-blur.js';
script.async = true;
document.head.appendChild(script);
});
</script>Licencia
Este componente está disponible bajo la Licencia MIT. Puedes usarlo libremente en proyectos comerciales y no comerciales.
MIT License
Copyright (c) 2024 CodeCopy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.HTML
1480
líneas
CSS
30
líneas
JavaScript
29
líneas
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Banner Cookies Lateral Blur</title>
<style>
:root {
--primary-color: #6366f1;
--primary-hover: #4f46e5;
--secondary-color: #8b5cf6;
--success-color: #10b981;
--success-hover: #059669;
--warning-color: #f59e0b;
--danger-color: #ef4444;
--background: #ffffff;
--surface: rgba(255, 255, 255, 0.9);
--surface-hover: rgba(255, 255, 255, 0.95);
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: rgba(255, 255, 255, 0.2);
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
--border-radius: 12px;
--border-radius-lg: 16px;
--border-radius-xl: 20px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
--transition-fast: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
--blur-amount: 20px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--text-primary);
line-height: 1.6;
padding: 2rem;
overflow-x: hidden;
position: relative;
}
.demo-container {
max-width: 1200px;
margin: 0 auto;
text-align: center;
color: white;
position: relative;
z-index: 1;
}
.demo-container h1 {
font-size: 3rem;
font-weight: 800;
margin-bottom: 1rem;
background: linear-gradient(135deg, #ffffff 0%, #f0f0f0 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.demo-container p {
font-size: 1.2rem;
opacity: 0.9;
margin-bottom: 2rem;
}
.demo-btn {
padding: 1rem 2rem;
border: none;
border-radius: var(--border-radius);
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
color: white;
font-family: inherit;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.demo-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
/* Superposición de Desenfoque de Fondo */
.blur-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
backdrop-filter: blur(var(--blur-amount));
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9998;
}
.blur-overlay.active {
opacity: 1;
visibility: visible;
}
/* Banner de Cookies Lateral con Blur */
.sidebar-blur-cookie-banner {
position: fixed;
top: 0;
right: 0;
width: 420px;
max-width: 90vw;
height: 100vh;
background: var(--surface);
backdrop-filter: blur(var(--blur-amount));
border-left: 1px solid var(--border-color);
transform: translateX(100%);
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9999;
display: flex;
flex-direction: column;
box-shadow: var(--shadow-xl);
overflow: hidden;
}
.sidebar-blur-cookie-banner.show {
transform: translateX(0);
}
.banner-header {
padding: 2rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
border-bottom: 1px solid var(--border-color);
position: relative;
}
.close-button {
position: absolute;
top: 1.5rem;
right: 1.5rem;
width: 40px;
height: 40px;
border: none;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
transition: var(--transition-fast);
font-size: 1.5rem;
border: 1px solid var(--border-color);
}
.close-button:hover {
background: rgba(255, 255, 255, 1);
color: var(--text-primary);
transform: scale(1.1);
box-shadow: var(--shadow-md);
}
.banner-title {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1rem;
}
.banner-icon {
width: 48px;
height: 48px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
border-radius: var(--border-radius);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: white;
animation: float 3s ease-in-out infinite;
box-shadow: var(--shadow-md);
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-5px);
}
}
.title-text {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-primary);
}
.banner-description {
color: var(--text-secondary);
font-size: 1rem;
line-height: 1.6;
}
/* Área de Contenido */
.banner-content {
flex: 1;
overflow-y: auto;
padding: 0;
scrollbar-width: thin;
scrollbar-color: rgba(99, 102, 241, 0.3) transparent;
}
.banner-content::-webkit-scrollbar {
width: 6px;
}
.banner-content::-webkit-scrollbar-track {
background: transparent;
}
.banner-content::-webkit-scrollbar-thumb {
background: rgba(99, 102, 241, 0.3);
border-radius: 3px;
}
.banner-content::-webkit-scrollbar-thumb:hover {
background: rgba(99, 102, 241, 0.5);
}
/* Categorías de Cookies */
.cookie-section {
padding: 1.5rem 2rem;
border-bottom: 1px solid var(--border-color);
}
.section-title {
font-size: 1.1rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.section-icon {
width: 20px;
height: 20px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
}
.cookie-category {
margin-bottom: 1rem;
padding: 1rem;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
background: rgba(255, 255, 255, 0.8);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-info {
flex: 1;
}
.category-title {
font-weight: 600;
font-size: 1rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.category-count {
font-size: 0.8rem;
color: var(--text-muted);
background: rgba(255, 255, 255, 0.8);
padding: 0.25rem 0.5rem;
border-radius: 12px;
display: inline-block;
}
.category-description {
font-size: 0.9rem;
color: var(--text-secondary);
line-height: 1.5;
margin-bottom: 0.75rem;
}
/* Interruptor Toggle */
.toggle-switch {
position: relative;
width: 56px;
height: 32px;
background: rgba(107, 114, 128, 0.3);
border-radius: 16px;
cursor: pointer;
transition: var(--transition);
flex-shrink: 0;
border: 1px solid var(--border-color);
backdrop-filter: blur(10px);
}
.toggle-switch.active {
background: linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%);
}
.toggle-switch.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.toggle-switch::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 26px;
height: 26px;
background: white;
border-radius: 50%;
transition: var(--transition);
box-shadow: var(--shadow-sm);
}
.toggle-switch.active::before {
transform: translateX(24px);
}
.toggle-switch:hover:not(.disabled) {
transform: scale(1.05);
}
/* Detalles Expandibles */
.expandable-section {
margin-top: 0.75rem;
}
.expand-toggle {
display: flex;
align-items: center;
gap: 0.5rem;
background: none;
border: none;
color: var(--primary-color);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: var(--transition-fast);
padding: 0.5rem;
border-radius: var(--border-radius);
width: 100%;
justify-content: flex-start;
}
.expand-toggle:hover {
background: rgba(99, 102, 241, 0.1);
}
.expand-icon {
transition: transform 0.3s ease;
}
.expand-toggle.expanded .expand-icon {
transform: rotate(180deg);
}
.expandable-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.expandable-content.expanded {
max-height: 300px;
}
.cookie-details {
padding: 1rem 0;
}
.cookie-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: var(--border-radius);
margin-bottom: 0.5rem;
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-item:hover {
background: rgba(255, 255, 255, 0.8);
}
.cookie-info {
flex: 1;
}
.cookie-name {
font-weight: 600;
font-size: 0.9rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.cookie-purpose {
font-size: 0.8rem;
color: var(--text-secondary);
line-height: 1.4;
}
.cookie-toggle {
width: 44px;
height: 24px;
background: rgba(107, 114, 128, 0.3);
border-radius: 12px;
position: relative;
cursor: pointer;
transition: var(--transition);
border: 1px solid var(--border-color);
}
.cookie-toggle.active {
background: var(--primary-color);
}
.cookie-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 18px;
height: 18px;
background: white;
border-radius: 50%;
transition: var(--transition);
}
.cookie-toggle.active::before {
transform: translateX(20px);
}
/* Botones de Acción */
.banner-actions {
padding: 2rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
border-top: 1px solid var(--border-color);
display: flex;
flex-direction: column;
gap: 1rem;
}
.action-button {
width: 100%;
padding: 1rem;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
text-transform: uppercase;
letter-spacing: 0.5px;
backdrop-filter: blur(10px);
border: 1px solid var(--border-color);
}
.action-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transition: left 0.5s ease;
}
.action-button:hover::before {
left: 100%;
}
.btn-accept {
background: linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%);
color: white;
box-shadow: var(--shadow-md);
}
.btn-accept:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-customize {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
color: white;
box-shadow: var(--shadow-md);
}
.btn-customize:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-reject {
background: rgba(239, 68, 68, 0.1);
color: var(--danger-color);
border: 1px solid rgba(239, 68, 68, 0.3);
}
.btn-reject:hover {
background: rgba(239, 68, 68, 0.2);
transform: translateY(-2px);
}
/* Panel de Estadísticas */
.stats-panel {
padding: 1.5rem 2rem;
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%);
border-bottom: 1px solid var(--border-color);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.stat-item {
text-align: center;
padding: 1rem;
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
}
.stat-number {
font-size: 1.5rem;
font-weight: 800;
color: var(--primary-color);
margin-bottom: 0.25rem;
}
.stat-label {
font-size: 0.8rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Estados de Carga */
.loading-spinner {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: currentColor;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Animación de Éxito */
.success-checkmark {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
stroke-width: 2;
stroke: currentColor;
stroke-miterlimit: 10;
box-shadow: inset 0px 0px 0px currentColor;
animation: fill 0.4s ease-in-out 0.4s forwards, scale 0.3s ease-in-out 0.9s both;
}
.checkmark-circle {
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
stroke-miterlimit: 10;
stroke: currentColor;
fill: none;
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
}
.checkmark-check {
transform-origin: 50% 50%;
stroke-dasharray: 48;
stroke-dashoffset: 48;
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
}
@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}
@keyframes scale {
0%, 100% {
transform: none;
}
50% {
transform: scale3d(1.1, 1.1, 1);
}
}
@keyframes fill {
100% {
box-shadow: inset 0px 0px 0px 30px currentColor;
}
}
/* Diseño Responsive */
@media (max-width: 768px) {
.sidebar-blur-cookie-banner {
width: 100%;
max-width: none;
border-left: none;
border-top: 1px solid var(--border-color);
}
.banner-header {
padding: 1.5rem;
}
.cookie-section {
padding: 1rem 1.5rem;
}
.banner-actions {
padding: 1.5rem;
}
.stats-grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-header {
padding: 1rem;
}
.cookie-section {
padding: 1rem;
}
.banner-actions {
padding: 1rem;
}
}
/* Variantes de Animación */
.slide-in-right {
animation: slideInRight 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.fade-in-up {
animation: fadeInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes fadeInUp {
from {
transform: translateY(30px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
/* Efectos Glassmorphism */
.glass-effect {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
}
.glass-effect-strong {
background: rgba(255, 255, 255, 0.4);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Diseño Lateral Blur</h1>
<p>Experimenta la elegancia del glassmorphism con sofisticados efectos de desenfoque y animaciones suaves de barra lateral</p>
<button class="demo-btn" onclick="mostrarBannerCookies()">Mostrar Banner de Cookies</button>
</div>
<!-- Superposición de Desenfoque -->
<div id="blurOverlay" class="blur-overlay"></div>
<!-- Banner de Cookies Lateral con Blur -->
<div id="sidebarBlurCookieBanner" class="sidebar-blur-cookie-banner">
<button class="close-button" onclick="cerrarBanner()" aria-label="Cerrar banner">×</button>
<div class="banner-header">
<div class="banner-title">
<div class="banner-icon">🍪</div>
<div class="title-text">Preferencias de Cookies</div>
</div>
<div class="banner-description">
Utilizamos cookies para mejorar tu experiencia de navegación y proporcionar contenido personalizado. Elige tus preferencias a continuación.
</div>
</div>
<div class="stats-panel">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-number">4</div>
<div class="stat-label">Categorías</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">Tipos de Cookies</div>
</div>
</div>
</div>
<div class="banner-content">
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">🔒</div>
Cookies Esenciales
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Estrictamente Necesarias <span class="category-count">Siempre Activas</span></div>
</div>
<div class="toggle-switch active disabled"></div>
</div>
<div class="category-description">
Estas cookies son esenciales para el funcionamiento del sitio web y no se pueden desactivar.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="essential-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="essential-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Cookie de Sesión</div>
<div class="cookie-purpose">Mantiene tu sesión mientras navegas</div>
</div>
<div class="cookie-toggle active"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Token de Seguridad</div>
<div class="cookie-purpose">Protege contra ataques de falsificación de solicitudes</div>
</div>
<div class="cookie-toggle active"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">📊</div>
Cookies de Análisis
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Análisis de Rendimiento <span class="category-count">3 cookies</span></div>
</div>
<div class="toggle-switch" data-category="analytics"></div>
</div>
<div class="category-description">
Nos ayudan a entender cómo los visitantes interactúan con nuestro sitio web recopilando información de forma anónima.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="analytics-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="analytics-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Google Analytics</div>
<div class="cookie-purpose">Rastrea el uso del sitio web y métricas de rendimiento</div>
</div>
<div class="cookie-toggle" data-cookie="ga"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Hotjar</div>
<div class="cookie-purpose">Registra interacciones de usuarios para mejoras de UX</div>
</div>
<div class="cookie-toggle" data-cookie="hotjar"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">🎯</div>
Cookies de Marketing
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Publicidad y Marketing <span class="category-count">5 cookies</span></div>
</div>
<div class="toggle-switch" data-category="marketing"></div>
</div>
<div class="category-description">
Se utilizan para ofrecer anuncios más relevantes basados en tu comportamiento de navegación.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="marketing-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="marketing-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Facebook Pixel</div>
<div class="cookie-purpose">Rastrea conversiones y construye audiencias</div>
</div>
<div class="cookie-toggle" data-cookie="facebook"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Google Ads</div>
<div class="cookie-purpose">Habilita remarketing y personalización de anuncios</div>
</div>
<div class="cookie-toggle" data-cookie="google-ads"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cookie-section">
<div class="section-title">
<div class="section-icon">⚙️</div>
Cookies Funcionales
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Funcionalidad Mejorada <span class="category-count">2 cookies</span></div>
</div>
<div class="toggle-switch" data-category="functional"></div>
</div>
<div class="category-description">
Habilitan funcionalidad mejorada y personalización, como videos y chats en vivo.
</div>
<div class="expandable-section">
<button class="expand-toggle" data-target="functional-details">
<span>Ver Detalles</span>
<span class="expand-icon">▼</span>
</button>
<div id="functional-details" class="expandable-content">
<div class="cookie-details">
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Preferencia de Idioma</div>
<div class="cookie-purpose">Recuerda tu idioma seleccionado</div>
</div>
<div class="cookie-toggle" data-cookie="language"></div>
</div>
<div class="cookie-item">
<div class="cookie-info">
<div class="cookie-name">Preferencia de Tema</div>
<div class="cookie-purpose">Guarda tu preferencia de modo oscuro/claro</div>
</div>
<div class="cookie-toggle" data-cookie="theme"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="banner-actions">
<button class="action-button btn-accept" onclick="aceptarTodasCookies()">Aceptar Todas las Cookies</button>
<button class="action-button btn-customize" onclick="guardarConfiguracionPersonalizada()">Guardar Mis Preferencias</button>
<button class="action-button btn-reject" onclick="rechazarCookiesOpcionales()">Rechazar Opcionales</button>
</div>
</div>
<script>
class BannerCookiesLateralBlur {
constructor(opciones = {}) {
this.opciones = {
mostrarAutomaticamente: true,
retrasoMostrar: 1500,
claveAlmacenamiento: 'sidebar_blur_cookie_consent',
diasExpiracion: 365,
habilitarAnimaciones: true,
cantidadBlur: '20px',
alAceptar: null,
alRechazar: null,
alGuardar: null,
alCerrar: null,
...opciones
};
this.banner = document.getElementById('sidebarBlurCookieBanner');
this.overlay = document.getElementById('blurOverlay');
this.consentimiento = this.obtenerConsentimientoAlmacenado();
this.esVisible = false;
this.inicializar();
}
inicializar() {
if (this.opciones.mostrarAutomaticamente && !this.consentimiento) {
setTimeout(() => this.mostrar(), this.opciones.retrasoMostrar);
}
this.configurarEventListeners();
this.cargarConfiguracion();
this.configurarCantidadBlur();
}
configurarEventListeners() {
// Interruptores toggle
document.querySelectorAll('.toggle-switch:not(.disabled)').forEach(toggle => {
toggle.addEventListener('click', () => {
this.alternarInterruptor(toggle);
});
});
// Toggles de cookies
document.querySelectorAll('.cookie-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
this.alternarInterruptorCookie(toggle);
});
});
// Secciones expandibles
document.querySelectorAll('.expand-toggle').forEach(button => {
button.addEventListener('click', () => {
this.alternarSeccionExpandible(button);
});
});
// Navegación por teclado
document.addEventListener('keydown', (e) => {
if (this.esVisible) {
this.manejarNavegacionTeclado(e);
}
});
// Clic en overlay para cerrar
this.overlay.addEventListener('click', () => {
this.cerrar();
});
// Efectos hover de botones
document.querySelectorAll('.action-button').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.crearRipple(btn);
});
});
}
configurarCantidadBlur() {
document.documentElement.style.setProperty('--blur-amount', this.opciones.cantidadBlur);
}
alternarInterruptor(toggle) {
if (toggle.classList.contains('disabled')) return;
toggle.classList.toggle('active');
if (this.opciones.habilitarAnimaciones) {
this.animarToggle(toggle);
}
// Actualizar toggles de cookies relacionados
const categoria = toggle.dataset.category;
if (categoria) {
this.actualizarTogglesCategorias(categoria, toggle.classList.contains('active'));
}
}
alternarInterruptorCookie(toggle) {
toggle.classList.toggle('active');
if (this.opciones.habilitarAnimaciones) {
this.animarToggle(toggle);
}
// Actualizar categoría padre si es necesario
this.actualizarEstadoCategoriasPadre();
}
actualizarTogglesCategorias(categoria, habilitado) {
const cookieToggles = document.querySelectorAll(`[data-cookie*="\${categoria}"]`);
cookieToggles.forEach(toggle => {
if (habilitado) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
});
}
actualizarEstadoCategoriasPadre() {
const categorias = ['analytics', 'marketing', 'functional'];
categorias.forEach(categoria => {
const categoryToggle = document.querySelector(`[data-category="\${categoria}"]`);
const cookieToggles = document.querySelectorAll(`[data-cookie*="\${categoria}"]`);
if (categoryToggle && cookieToggles.length > 0) {
const todosHabilitados = Array.from(cookieToggles).every(toggle =>
toggle.classList.contains('active'));
if (todosHabilitados) {
categoryToggle.classList.add('active');
} else {
categoryToggle.classList.remove('active');
}
}
});
}
alternarSeccionExpandible(button) {
const targetId = button.dataset.target;
const content = document.getElementById(targetId);
if (content) {
const estaExpandido = content.classList.contains('expanded');
if (estaExpandido) {
content.classList.remove('expanded');
button.classList.remove('expanded');
} else {
content.classList.add('expanded');
button.classList.add('expanded');
if (this.opciones.habilitarAnimaciones) {
this.animarContenidoExpandible(content);
}
}
}
}
animarContenidoExpandible(content) {
const items = content.querySelectorAll('.cookie-item');
items.forEach((item, index) => {
item.style.opacity = '0';
item.style.transform = 'translateY(10px)';
setTimeout(() => {
item.style.transition = 'all 0.3s ease';
item.style.opacity = '1';
item.style.transform = 'translateY(0)';
}, index * 50);
});
}
animarToggle(toggle) {
toggle.style.transform = 'scale(0.95)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
// Agregar efecto de pulso
const color = toggle.classList.contains('active') ?
'rgba(16, 185, 129, 0.3)' : 'rgba(107, 114, 128, 0.3)';
toggle.style.boxShadow = `0 0 0 8px \${color}`;
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
manejarNavegacionTeclado(e) {
switch (e.key) {
case 'Escape':
this.cerrar();
break;
case 'Tab':
// Dejar que el navegador maneje la navegación por tab
break;
}
}
crearRipple(button) {
if (!this.opciones.habilitarAnimaciones) return;
const ripple = document.createElement('span');
const rect = button.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = '50%';
ripple.style.top = '50%';
ripple.style.transform = 'translate(-50%, -50%) scale(0)';
ripple.style.position = 'absolute';
ripple.style.borderRadius = '50%';
ripple.style.background = 'rgba(255, 255, 255, 0.3)';
ripple.style.pointerEvents = 'none';
ripple.style.animation = 'ripple 0.6s ease-out';
button.style.position = 'relative';
button.style.overflow = 'hidden';
button.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
}
mostrar() {
this.banner.classList.add('show');
this.overlay.classList.add('active');
this.esVisible = true;
if (this.opciones.habilitarAnimaciones) {
this.animarEntrada();
}
}
ocultar() {
this.banner.classList.remove('show');
this.overlay.classList.remove('active');
this.esVisible = false;
}
cerrar() {
this.ocultar();
if (this.opciones.alCerrar) {
this.opciones.alCerrar();
}
}
animarEntrada() {
const sections = this.banner.querySelectorAll('.cookie-section');
sections.forEach((section, index) => {
section.style.opacity = '0';
section.style.transform = 'translateX(30px)';
setTimeout(() => {
section.style.transition = 'all 0.5s cubic-bezier(0.4, 0, 0.2, 1)';
section.style.opacity = '1';
section.style.transform = 'translateX(0)';
}, index * 100);
});
}
aceptarTodasCookies() {
const consentimiento = {
esencial: true,
analytics: true,
marketing: true,
funcional: true,
timestamp: Date.now()
};
this.guardarConsentimiento(consentimiento);
this.mostrarAnimacionExito();
setTimeout(() => {
this.ocultar();
}, 1500);
if (this.opciones.alAceptar) {
this.opciones.alAceptar(consentimiento);
}
}
rechazarCookiesOpcionales() {
const consentimiento = {
esencial: true,
analytics: false,
marketing: false,
funcional: false,
timestamp: Date.now()
};
this.guardarConsentimiento(consentimiento);
this.ocultar();
if (this.opciones.alRechazar) {
this.opciones.alRechazar(consentimiento);
}
}
guardarConfiguracionPersonalizada() {
const consentimiento = { timestamp: Date.now() };
// Obtener estados de categorías
consentimiento.esencial = true; // Siempre verdadero
consentimiento.analytics = document.querySelector('[data-category="analytics"]')?.classList.contains('active') || false;
consentimiento.marketing = document.querySelector('[data-category="marketing"]')?.classList.contains('active') || false;
consentimiento.funcional = document.querySelector('[data-category="functional"]')?.classList.contains('active') || false;
// Obtener estados de cookies individuales
const estadosCookies = {};
document.querySelectorAll('[data-cookie]').forEach(toggle => {
const cookie = toggle.dataset.cookie;
estadosCookies[cookie] = toggle.classList.contains('active');
});
consentimiento.cookies = estadosCookies;
this.guardarConsentimiento(consentimiento);
this.mostrarAnimacionExito();
setTimeout(() => {
this.ocultar();
}, 1500);
if (this.opciones.alGuardar) {
this.opciones.alGuardar(consentimiento);
}
}
mostrarAnimacionExito() {
if (!this.opciones.habilitarAnimaciones) return;
const customizeBtn = this.banner.querySelector('.btn-customize');
if (customizeBtn) {
customizeBtn.innerHTML = `
<svg class="success-checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<circle class="checkmark-circle" cx="26" cy="26" r="25" fill="none"/>
<path class="checkmark-check" fill="none" d="m14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
Preferencias Guardadas
`;
customizeBtn.style.background = 'linear-gradient(135deg, var(--success-color) 0%, #06d6a0 100%)';
}
}
cargarConfiguracion() {
if (this.consentimiento) {
// Cargar estados de categorías
Object.entries(this.consentimiento).forEach(([key, value]) => {
if (typeof value === 'boolean') {
const toggle = document.querySelector(`[data-category="\${key}"]`);
if (toggle && !toggle.classList.contains('disabled')) {
if (value) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
}
});
// Cargar estados de cookies individuales
if (this.consentimiento.cookies) {
Object.entries(this.consentimiento.cookies).forEach(([cookie, habilitado]) => {
const toggle = document.querySelector(`[data-cookie="\${cookie}"]`);
if (toggle) {
if (habilitado) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
}
}
guardarConsentimiento(consentimiento) {
const fechaExpiracion = new Date();
fechaExpiracion.setDate(fechaExpiracion.getDate() + this.opciones.diasExpiracion);
const datosConsentimiento = {
...consentimiento,
expiracion: fechaExpiracion.getTime()
};
localStorage.setItem(this.opciones.claveAlmacenamiento, JSON.stringify(datosConsentimiento));
this.consentimiento = consentimiento;
}
obtenerConsentimientoAlmacenado() {
try {
const almacenado = localStorage.getItem(this.opciones.claveAlmacenamiento);
if (almacenado) {
const datos = JSON.parse(almacenado);
if (datos.expiracion && Date.now() < datos.expiracion) {
return datos;
} else {
localStorage.removeItem(this.opciones.claveAlmacenamiento);
}
}
} catch (e) {
console.error('Error al leer consentimiento de cookies:', e);
}
return null;
}
reiniciar() {
localStorage.removeItem(this.opciones.claveAlmacenamiento);
this.consentimiento = null;
this.mostrar();
}
obtenerConsentimiento() {
return this.consentimiento;
}
establecerCantidadBlur(cantidad) {
this.opciones.cantidadBlur = cantidad;
this.configurarCantidadBlur();
}
habilitarAnimaciones(habilitado) {
this.opciones.habilitarAnimaciones = habilitado;
}
actualizarTema(tema) {
const temas = {
claro: {
'--background': '#ffffff',
'--surface': 'rgba(255, 255, 255, 0.9)',
'--text-primary': '#1f2937',
'--text-secondary': '#6b7280'
},
oscuro: {
'--background': '#1f2937',
'--surface': 'rgba(31, 41, 55, 0.9)',
'--text-primary': '#f9fafb',
'--text-secondary': '#d1d5db'
}
};
if (temas[tema]) {
Object.entries(temas[tema]).forEach(([propiedad, valor]) => {
document.documentElement.style.setProperty(propiedad, valor);
});
}
}
}
// Agregar CSS para animación ripple
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Inicializar el banner
const bannerCookies = new BannerCookiesLateralBlur({
cantidadBlur: '20px',
habilitarAnimaciones: true,
alAceptar: (consentimiento) => {
console.log('Cookies aceptadas:', consentimiento);
// Inicializar scripts de analytics, marketing, etc.
},
alRechazar: (consentimiento) => {
console.log('Cookies opcionales rechazadas:', consentimiento);
// Cargar solo scripts esenciales
},
alGuardar: (consentimiento) => {
console.log('Configuración personalizada guardada:', consentimiento);
// Cargar scripts basados en preferencias del usuario
},
alCerrar: () => {
console.log('Banner cerrado sin acción');
}
});
// Funciones globales para demo
function mostrarBannerCookies() {
bannerCookies.reiniciar();
}
function cerrarBanner() {
bannerCookies.cerrar();
}
function aceptarTodasCookies() {
bannerCookies.aceptarTodasCookies();
}
function rechazarCookiesOpcionales() {
bannerCookies.rechazarCookiesOpcionales();
}
function guardarConfiguracionPersonalizada() {
bannerCookies.guardarConfiguracionPersonalizada();
}
</script>
</body>
</html>