Interactive Cookie Consent Banner with Tabs
A sophisticated interactive cookie consent banner featuring tabbed navigation, detailed settings options, and advanced customization controls for comprehensive privacy management
Responsive Design
Yes
Dark Mode Support
No
lines
1611
Browser Compatibility
No
Live Preview
Interact with the component without leaving the page.
Interactive Cookie Consent Banner with Tabs
A comprehensive and interactive cookie consent banner featuring tabbed navigation, detailed settings options, and advanced customization controls. This banner provides users with granular control over their privacy preferences while maintaining a clean and intuitive interface that ensures GDPR compliance.
Features
- Tabbed Navigation: Organized interface with multiple tabs for different cookie categories
- Interactive Settings: Detailed controls for each cookie type with descriptions
- Advanced Customization: Granular options for cookie preferences and data handling
- Progressive Disclosure: Expandable sections for detailed information
- Real-time Preview: Live preview of settings changes
- GDPR Compliant: Complete consent management with audit trail
- Accessibility First: Full keyboard navigation and screen reader support
- Responsive Design: Adapts beautifully to all screen sizes and orientations
- Modern UI: Clean, professional interface with smooth animations
- Performance Optimized: Lightweight implementation with fast loading
Preview
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Tabs Cookie Banner</title>
<style>
:root {
--primary-color: #3b82f6;
--primary-hover: #2563eb;
--secondary-color: #6b7280;
--success-color: #10b981;
--success-hover: #059669;
--warning-color: #f59e0b;
--warning-hover: #d97706;
--danger-color: #ef4444;
--danger-hover: #dc2626;
--background: #ffffff;
--surface: #f8fafc;
--surface-hover: #f1f5f9;
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: #e5e7eb;
--border-hover: #d1d5db;
--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: 8px;
--border-radius-lg: 12px;
--border-radius-xl: 16px;
--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);
}
* {
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;
}
.demo-container {
max-width: 1200px;
margin: 0 auto;
text-align: center;
color: white;
}
.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);
}
/* Interactive Tabs Cookie Banner */
.interactive-tabs-cookie-banner {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 480px;
max-width: calc(100vw - 4rem);
background: var(--background);
border-radius: var(--border-radius-xl);
box-shadow: var(--shadow-xl);
border: 1px solid var(--border-color);
transform: translateX(120%);
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10000;
backdrop-filter: blur(20px);
overflow: hidden;
}
.interactive-tabs-cookie-banner.show {
transform: translateX(0);
}
.banner-header {
padding: 1.5rem;
border-bottom: 1px solid var(--border-color);
background: linear-gradient(135deg, var(--surface) 0%, var(--background) 100%);
}
.banner-title {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.5rem;
}
.banner-icon {
width: 32px;
height: 32px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
color: white;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);
}
}
.title-text {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
}
.banner-description {
color: var(--text-secondary);
font-size: 0.9rem;
line-height: 1.5;
}
.close-button {
position: absolute;
top: 1rem;
right: 1rem;
width: 32px;
height: 32px;
border: none;
background: var(--surface);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
transition: var(--transition-fast);
font-size: 1.2rem;
}
.close-button:hover {
background: var(--border-color);
color: var(--text-primary);
transform: scale(1.1);
}
/* Tab Navigation */
.tab-navigation {
display: flex;
background: var(--surface);
border-bottom: 1px solid var(--border-color);
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tab-navigation::-webkit-scrollbar {
display: none;
}
.tab-button {
flex: 1;
min-width: 120px;
padding: 1rem 0.75rem;
border: none;
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition-fast);
position: relative;
white-space: nowrap;
}
.tab-button.active {
color: var(--primary-color);
background: var(--background);
}
.tab-button::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background: var(--primary-color);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.tab-button.active::after {
transform: scaleX(1);
}
.tab-button:hover {
color: var(--primary-hover);
background: var(--surface-hover);
}
/* Tab Content */
.tab-content {
max-height: 400px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--border-color) transparent;
}
.tab-content::-webkit-scrollbar {
width: 6px;
}
.tab-content::-webkit-scrollbar-track {
background: transparent;
}
.tab-content::-webkit-scrollbar-thumb {
background: var(--border-color);
border-radius: 3px;
}
.tab-panel {
display: none;
padding: 1.5rem;
animation: fadeIn 0.3s ease;
}
.tab-panel.active {
display: block;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Cookie Category */
.cookie-category {
margin-bottom: 1.5rem;
padding: 1rem;
background: var(--surface);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
box-shadow: var(--shadow-md);
border-color: var(--border-hover);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-info {
flex: 1;
}
.category-title {
font-weight: 700;
font-size: 1rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.category-count {
font-size: 0.8rem;
color: var(--text-muted);
background: var(--background);
padding: 0.25rem 0.5rem;
border-radius: 12px;
display: inline-block;
}
.category-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
margin-bottom: 1rem;
}
/* Toggle Switch */
.toggle-switch {
position: relative;
width: 52px;
height: 28px;
background: var(--border-color);
border-radius: 14px;
cursor: pointer;
transition: var(--transition);
flex-shrink: 0;
}
.toggle-switch.active {
background: var(--success-color);
}
.toggle-switch.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.toggle-switch::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 24px;
height: 24px;
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);
}
/* Cookie Details */
.cookie-details {
margin-top: 1rem;
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: var(--background);
border-radius: var(--border-radius);
margin-bottom: 0.5rem;
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.detail-item:hover {
background: var(--surface-hover);
}
.detail-info {
flex: 1;
}
.detail-name {
font-weight: 600;
font-size: 0.9rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.detail-description {
font-size: 0.8rem;
color: var(--text-secondary);
line-height: 1.4;
}
.detail-toggle {
width: 40px;
height: 20px;
background: var(--border-color);
border-radius: 10px;
position: relative;
cursor: pointer;
transition: var(--transition);
}
.detail-toggle.active {
background: var(--primary-color);
}
.detail-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
background: white;
border-radius: 50%;
transition: var(--transition);
}
.detail-toggle.active::before {
transform: translateX(20px);
}
/* Action Buttons */
.banner-actions {
padding: 1.5rem;
border-top: 1px solid var(--border-color);
background: var(--surface);
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.action-button {
flex: 1;
min-width: 120px;
padding: 0.75rem 1rem;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.action-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
.action-button:hover::before {
left: 100%;
}
.btn-accept {
background: var(--success-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-accept:hover {
background: var(--success-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-reject {
background: var(--danger-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-reject:hover {
background: var(--danger-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-save {
background: var(--primary-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-save:hover {
background: var(--primary-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
/* Statistics Panel */
.stats-panel {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.stat-item {
text-align: center;
padding: 1rem;
background: var(--surface);
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;
}
/* Privacy Settings */
.privacy-setting {
margin-bottom: 1rem;
padding: 1rem;
background: var(--background);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
}
.setting-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.setting-title {
font-weight: 600;
color: var(--text-primary);
}
.setting-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
}
/* Loading States */
.loading-dots {
display: inline-flex;
gap: 4px;
}
.loading-dots span {
width: 6px;
height: 6px;
background: currentColor;
border-radius: 50%;
animation: loading 1.4s infinite ease-in-out;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
@keyframes loading {
0%, 80%, 100% {
transform: scale(0.8);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
/* Success Animation */
.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;
}
}
/* Responsive Design */
@media (max-width: 768px) {
.interactive-tabs-cookie-banner {
bottom: 0;
right: 0;
left: 0;
width: 100%;
max-width: none;
border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
transform: translateY(100%);
}
.interactive-tabs-cookie-banner.show {
transform: translateY(0);
}
.tab-navigation {
overflow-x: auto;
}
.tab-button {
min-width: 100px;
font-size: 0.8rem;
}
.banner-actions {
flex-direction: column;
}
.action-button {
width: 100%;
min-width: auto;
}
.stats-panel {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-header {
padding: 1rem;
}
.tab-panel {
padding: 1rem;
}
.banner-actions {
padding: 1rem;
}
}
/* Animation Variants */
.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;
}
}
.bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes bounceIn {
0% {
transform: translateX(100%) scale(0.3);
opacity: 0;
}
50% {
transform: translateX(-10%) scale(1.05);
}
70% {
transform: translateX(5%) scale(0.98);
}
100% {
transform: translateX(0) scale(1);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Interactive Tabs Design</h1>
<p>Experience the power of tabbed navigation with detailed settings and advanced customization options</p>
<button class="demo-btn" onclick="showCookieBanner()">Show Cookie Banner</button>
</div>
<!-- Interactive Tabs Cookie Banner -->
<div id="interactiveTabsCookieBanner" class="interactive-tabs-cookie-banner">
<button class="close-button" onclick="closeBanner()" aria-label="Close banner">×</button>
<div class="banner-header">
<div class="banner-title">
<div class="banner-icon">🍪</div>
<div class="title-text">Cookie Preferences</div>
</div>
<div class="banner-description">
We use cookies to enhance your browsing experience and provide personalized content. Choose your preferences below.
</div>
</div>
<div class="tab-navigation">
<button class="tab-button active" data-tab="overview">Overview</button>
<button class="tab-button" data-tab="essential">Essential</button>
<button class="tab-button" data-tab="analytics">Analytics</button>
<button class="tab-button" data-tab="marketing">Marketing</button>
<button class="tab-button" data-tab="preferences">Preferences</button>
</div>
<div class="tab-content">
<!-- Overview Tab -->
<div id="overview" class="tab-panel active">
<div class="stats-panel">
<div class="stat-item">
<div class="stat-number">4</div>
<div class="stat-label">Categories</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">Cookie Types</div>
</div>
<div class="stat-item">
<div class="stat-number">365</div>
<div class="stat-label">Days Stored</div>
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Essential Cookies <span class="category-count">Always Active</span></div>
</div>
<div class="toggle-switch active disabled"></div>
</div>
<div class="category-description">
These cookies are necessary for the website to function and cannot be switched off.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Analytics Cookies <span class="category-count">3 cookies</span></div>
</div>
<div class="toggle-switch" data-category="analytics"></div>
</div>
<div class="category-description">
Help us understand how visitors interact with our website by collecting information anonymously.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Marketing Cookies <span class="category-count">5 cookies</span></div>
</div>
<div class="toggle-switch" data-category="marketing"></div>
</div>
<div class="category-description">
Used to deliver more relevant advertisements based on your browsing behavior.
</div>
</div>
</div>
<!-- Essential Tab -->
<div id="essential" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Session Cookie</div>
<div class="detail-description">Maintains your session while browsing</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Security Token</div>
<div class="detail-description">Protects against cross-site request forgery</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Language Preference</div>
<div class="detail-description">Remembers your selected language</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Cookie Consent</div>
<div class="detail-description">Stores your cookie preferences</div>
</div>
<div class="detail-toggle active"></div>
</div>
</div>
</div>
<!-- Analytics Tab -->
<div id="analytics" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Google Analytics</div>
<div class="detail-description">Tracks website usage and performance metrics</div>
</div>
<div class="detail-toggle" data-cookie="ga"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Hotjar</div>
<div class="detail-description">Records user interactions for UX improvements</div>
</div>
<div class="detail-toggle" data-cookie="hotjar"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Performance Monitoring</div>
<div class="detail-description">Monitors site speed and performance</div>
</div>
<div class="detail-toggle" data-cookie="performance"></div>
</div>
</div>
</div>
<!-- Marketing Tab -->
<div id="marketing" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Facebook Pixel</div>
<div class="detail-description">Tracks conversions and builds audiences</div>
</div>
<div class="detail-toggle" data-cookie="facebook"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Google Ads</div>
<div class="detail-description">Enables remarketing and ad personalization</div>
</div>
<div class="detail-toggle" data-cookie="google-ads"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">LinkedIn Insight</div>
<div class="detail-description">Tracks professional audience engagement</div>
</div>
<div class="detail-toggle" data-cookie="linkedin"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Twitter Analytics</div>
<div class="detail-description">Measures social media campaign effectiveness</div>
</div>
<div class="detail-toggle" data-cookie="twitter"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Affiliate Tracking</div>
<div class="detail-description">Tracks referrals and commission attribution</div>
</div>
<div class="detail-toggle" data-cookie="affiliate"></div>
</div>
</div>
</div>
<!-- Preferences Tab -->
<div id="preferences" class="tab-panel">
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Data Retention Period</div>
<select class="setting-control">
<option value="30">30 days</option>
<option value="90">90 days</option>
<option value="365" selected>1 year</option>
<option value="730">2 years</option>
</select>
</div>
<div class="setting-description">
How long we keep your data before automatic deletion.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Data Sharing</div>
<div class="toggle-switch" data-setting="sharing"></div>
</div>
<div class="setting-description">
Allow sharing anonymized data with trusted partners for research.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Personalized Experience</div>
<div class="toggle-switch active" data-setting="personalization"></div>
</div>
<div class="setting-description">
Enable personalized content and recommendations based on your activity.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Email Notifications</div>
<div class="toggle-switch" data-setting="notifications"></div>
</div>
<div class="setting-description">
Receive updates about privacy policy changes and new features.
</div>
</div>
</div>
</div>
<div class="banner-actions">
<button class="action-button btn-accept" onclick="acceptAllCookies()">Accept All</button>
<button class="action-button btn-reject" onclick="rejectOptionalCookies()">Reject Optional</button>
<button class="action-button btn-save" onclick="saveCustomSettings()">Save Settings</button>
</div>
</div>
<script>
class InteractiveTabsCookieBanner {
constructor(options = {}) {
this.options = {
autoShow: true,
showDelay: 1500,
storageKey: 'interactive_tabs_cookie_consent',
expirationDays: 365,
enableAnimations: true,
animationType: 'slide', // 'slide', 'bounce', 'fade'
onAccept: null,
onReject: null,
onSave: null,
onClose: null,
...options
};
this.banner = document.getElementById('interactiveTabsCookieBanner');
this.consent = this.getStoredConsent();
this.isVisible = false;
this.activeTab = 'overview';
this.initialize();
}
initialize() {
if (this.options.autoShow && !this.consent) {
setTimeout(() => this.show(), this.options.showDelay);
}
this.setupEventListeners();
this.loadSettings();
this.setupAnimationType();
}
setupEventListeners() {
// Tab navigation
document.querySelectorAll('.tab-button').forEach(button => {
button.addEventListener('click', () => {
this.switchTab(button.dataset.tab);
});
});
// Toggle switches
document.querySelectorAll('.toggle-switch:not(.disabled)').forEach(toggle => {
toggle.addEventListener('click', () => {
this.toggleSwitch(toggle);
});
});
// Detail toggles
document.querySelectorAll('.detail-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
this.toggleDetailSwitch(toggle);
});
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (this.isVisible) {
this.handleKeyboardNavigation(e);
}
});
// Button hover effects
document.querySelectorAll('.action-button').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.createRipple(btn);
});
});
}
setupAnimationType() {
const animationClasses = {
slide: 'slide-in-right',
bounce: 'bounce-in',
fade: 'fade-in'
};
const animationClass = animationClasses[this.options.animationType];
if (animationClass) {
this.banner.classList.add(animationClass);
}
}
switchTab(tabName) {
// Update active tab button
document.querySelectorAll('.tab-button').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
// Update active tab panel
document.querySelectorAll('.tab-panel').forEach(panel => {
panel.classList.remove('active');
});
document.getElementById(tabName).classList.add('active');
this.activeTab = tabName;
if (this.options.enableAnimations) {
this.animateTabSwitch(tabName);
}
}
animateTabSwitch(tabName) {
const panel = document.getElementById(tabName);
const elements = panel.querySelectorAll('.cookie-category, .detail-item, .privacy-setting, .stat-item');
elements.forEach((el, index) => {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
setTimeout(() => {
el.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, index * 50);
});
}
toggleSwitch(toggle) {
toggle.classList.toggle('active');
if (this.options.enableAnimations) {
this.animateToggle(toggle);
}
// Update category state
const category = toggle.dataset.category;
if (category) {
this.updateCategoryState(category, toggle.classList.contains('active'));
}
}
toggleDetailSwitch(toggle) {
toggle.classList.toggle('active');
if (this.options.enableAnimations) {
this.animateToggle(toggle);
}
// Update individual cookie state
const cookie = toggle.dataset.cookie;
if (cookie) {
this.updateCookieState(cookie, toggle.classList.contains('active'));
}
}
animateToggle(toggle) {
toggle.style.transform = 'scale(0.9)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
// Add pulse effect
const color = toggle.classList.contains('active') ?
'rgba(16, 185, 129, 0.2)' : 'rgba(107, 114, 128, 0.2)';
toggle.style.boxShadow = `0 0 0 8px ${color}`;
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
updateCategoryState(category, enabled) {
// Update all related detail toggles
const detailToggles = document.querySelectorAll(`[data-cookie^="${category}"]`);
detailToggles.forEach(toggle => {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
});
}
updateCookieState(cookie, enabled) {
// Update parent category if all cookies are enabled/disabled
this.updateParentCategoryState();
}
updateParentCategoryState() {
const categories = ['analytics', 'marketing'];
categories.forEach(category => {
const categoryToggle = document.querySelector(`[data-category="${category}"]`);
const cookieToggles = document.querySelectorAll(`[data-cookie*="${category}"]`);
if (categoryToggle && cookieToggles.length > 0) {
const allEnabled = Array.from(cookieToggles).every(toggle =>
toggle.classList.contains('active'));
const anyEnabled = Array.from(cookieToggles).some(toggle =>
toggle.classList.contains('active'));
if (allEnabled) {
categoryToggle.classList.add('active');
} else {
categoryToggle.classList.remove('active');
}
}
});
}
handleKeyboardNavigation(e) {
switch (e.key) {
case 'Escape':
this.close();
break;
case 'Tab':
// Let browser handle tab navigation
break;
case 'ArrowLeft':
case 'ArrowRight':
if (e.target.classList.contains('tab-button')) {
this.navigateTabs(e.key === 'ArrowRight' ? 1 : -1);
e.preventDefault();
}
break;
}
}
navigateTabs(direction) {
const tabs = Array.from(document.querySelectorAll('.tab-button'));
const currentIndex = tabs.findIndex(tab => tab.classList.contains('active'));
const newIndex = (currentIndex + direction + tabs.length) % tabs.length;
this.switchTab(tabs[newIndex].dataset.tab);
tabs[newIndex].focus();
}
createRipple(button) {
if (!this.options.enableAnimations) 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);
}
show() {
this.banner.classList.add('show');
this.isVisible = true;
if (this.options.enableAnimations) {
this.animateEntrance();
}
}
hide() {
this.banner.classList.remove('show');
this.isVisible = false;
}
close() {
this.hide();
if (this.options.onClose) {
this.options.onClose();
}
}
animateEntrance() {
const elements = [
this.banner.querySelector('.banner-header'),
this.banner.querySelector('.tab-navigation'),
this.banner.querySelector('.tab-content'),
this.banner.querySelector('.banner-actions')
];
elements.forEach((el, index) => {
if (el) {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
setTimeout(() => {
el.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, index * 100);
}
});
}
acceptAllCookies() {
const consent = {
essential: true,
analytics: true,
marketing: true,
functional: true,
timestamp: Date.now()
};
this.saveConsent(consent);
this.showSuccessAnimation();
setTimeout(() => {
this.hide();
}, 1500);
if (this.options.onAccept) {
this.options.onAccept(consent);
}
}
rejectOptionalCookies() {
const consent = {
essential: true,
analytics: false,
marketing: false,
functional: false,
timestamp: Date.now()
};
this.saveConsent(consent);
this.hide();
if (this.options.onReject) {
this.options.onReject(consent);
}
}
saveCustomSettings() {
const toggles = document.querySelectorAll('.toggle-switch, .detail-toggle');
const consent = { timestamp: Date.now() };
// Get category states
consent.essential = true; // Always true
consent.analytics = document.querySelector('[data-category="analytics"]')?.classList.contains('active') || false;
consent.marketing = document.querySelector('[data-category="marketing"]')?.classList.contains('active') || false;
consent.functional = true; // Assume functional if not explicitly set
// Get individual cookie states
const cookieStates = {};
document.querySelectorAll('[data-cookie]').forEach(toggle => {
const cookie = toggle.dataset.cookie;
cookieStates[cookie] = toggle.classList.contains('active');
});
consent.cookies = cookieStates;
// Get preference settings
const settings = {};
document.querySelectorAll('[data-setting]').forEach(toggle => {
const setting = toggle.dataset.setting;
settings[setting] = toggle.classList.contains('active');
});
consent.settings = settings;
this.saveConsent(consent);
this.showSuccessAnimation();
setTimeout(() => {
this.hide();
}, 1500);
if (this.options.onSave) {
this.options.onSave(consent);
}
}
showSuccessAnimation() {
if (!this.options.enableAnimations) return;
const saveBtn = this.banner.querySelector('.btn-save');
if (saveBtn) {
saveBtn.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>
Saved
`;
saveBtn.style.background = 'var(--success-color)';
}
}
loadSettings() {
if (this.consent) {
// Load category states
Object.entries(this.consent).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');
}
}
}
});
// Load individual cookie states
if (this.consent.cookies) {
Object.entries(this.consent.cookies).forEach(([cookie, enabled]) => {
const toggle = document.querySelector(`[data-cookie="${cookie}"]`);
if (toggle) {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
// Load preference settings
if (this.consent.settings) {
Object.entries(this.consent.settings).forEach(([setting, enabled]) => {
const toggle = document.querySelector(`[data-setting="${setting}"]`);
if (toggle) {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
}
}
saveConsent(consent) {
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + this.options.expirationDays);
const consentData = {
...consent,
expiration: expirationDate.getTime()
};
localStorage.setItem(this.options.storageKey, JSON.stringify(consentData));
this.consent = consent;
}
getStoredConsent() {
try {
const stored = localStorage.getItem(this.options.storageKey);
if (stored) {
const data = JSON.parse(stored);
if (data.expiration && Date.now() < data.expiration) {
return data;
} else {
localStorage.removeItem(this.options.storageKey);
}
}
} catch (e) {
console.error('Error reading cookie consent:', e);
}
return null;
}
reset() {
localStorage.removeItem(this.options.storageKey);
this.consent = null;
this.show();
}
getConsent() {
return this.consent;
}
setAnimationType(type) {
this.options.animationType = type;
this.setupAnimationType();
}
enableAnimations(enabled) {
this.options.enableAnimations = enabled;
}
updateTheme(theme) {
const themes = {
light: {
'--background': '#ffffff',
'--surface': '#f8fafc',
'--text-primary': '#1f2937',
'--text-secondary': '#6b7280'
},
dark: {
'--background': '#1f2937',
'--surface': '#374151',
'--text-primary': '#f9fafb',
'--text-secondary': '#d1d5db'
}
};
if (themes[theme]) {
Object.entries(themes[theme]).forEach(([property, value]) => {
document.documentElement.style.setProperty(property, value);
});
}
}
}
// Add ripple animation CSS
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Initialize the banner
const cookieBanner = new InteractiveTabsCookieBanner({
animationType: 'slide',
enableAnimations: true,
onAccept: (consent) => {
console.log('Cookies accepted:', consent);
// Initialize analytics, marketing scripts, etc.
},
onReject: (consent) => {
console.log('Optional cookies rejected:', consent);
// Load only essential scripts
},
onSave: (consent) => {
console.log('Custom settings saved:', consent);
// Load scripts based on user preferences
},
onClose: () => {
console.log('Banner closed without action');
}
});
// Global functions for demo
function showCookieBanner() {
cookieBanner.reset();
}
function closeBanner() {
cookieBanner.close();
}
function acceptAllCookies() {
cookieBanner.acceptAllCookies();
}
function rejectOptionalCookies() {
cookieBanner.rejectOptionalCookies();
}
function saveCustomSettings() {
cookieBanner.saveCustomSettings();
}
</script>
</body>
</html>Usage
Basic Implementation
// Initialize with default settings
const cookieBanner = new InteractiveTabsCookieBanner();
// Initialize with custom options
const cookieBanner = new InteractiveTabsCookieBanner({
autoShow: true,
showDelay: 2000,
storageKey: 'my_cookie_consent',
expirationDays: 180,
enableAnimations: true,
animationType: 'slide',
onAccept: (consent) => {
console.log('User accepted cookies:', consent);
// Load analytics scripts
if (consent.analytics) {
loadGoogleAnalytics();
}
// Load marketing scripts
if (consent.marketing) {
loadMarketingPixels();
}
},
onReject: (consent) => {
console.log('User rejected optional cookies:', consent);
// Load only essential functionality
},
onSave: (consent) => {
console.log('User saved custom settings:', consent);
// Load scripts based on specific preferences
}
});Advanced Configuration
// Advanced setup with detailed control
const advancedBanner = new InteractiveTabsCookieBanner({
autoShow: false, // Manual control
showDelay: 0,
storageKey: 'advanced_consent',
expirationDays: 90,
enableAnimations: true,
animationType: 'bounce',
// Advanced callbacks
onAccept: (consent) => {
// Advanced analytics setup
initializeAdvancedTracking(consent);
},
onReject: (consent) => {
// Minimal tracking setup
initializeEssentialOnly();
},
onSave: (consent) => {
// Granular script loading
loadScriptsBasedOnConsent(consent);
},
onClose: () => {
// Handle banner close without action
logUserInteraction('banner_closed');
}
});
// Show banner manually
advancedBanner.show();Theme Customization
// Switch to dark theme
cookieBanner.updateTheme('dark');
// Switch to light theme
cookieBanner.updateTheme('light');
// Disable animations
cookieBanner.enableAnimations(false);
// Change animation type
cookieBanner.setAnimationType('bounce');API Methods
Core Methods
show()- Display the cookie bannerhide()- Hide the cookie bannerclose()- Close the banner and trigger onClose callbackreset()- Clear stored consent and show banner againgetConsent()- Get current consent statussaveConsent(consent)- Save consent data manually
Configuration Methods
setAnimationType(type)- Change animation type (‘slide’, ‘bounce’, ‘fade’)enableAnimations(enabled)- Enable/disable animationsupdateTheme(theme)- Switch between ‘light’ and ‘dark’ themes
Event Handling
onAccept(callback)- Called when user accepts all cookiesonReject(callback)- Called when user rejects optional cookiesonSave(callback)- Called when user saves custom settingsonClose(callback)- Called when banner is closed
Customization Options
Animation Types
// Slide animation (default)
animationType: 'slide'
// Bounce animation
animationType: 'bounce'
// Fade animation
animationType: 'fade'Storage Configuration
// Custom storage key
storageKey: 'my_custom_consent_key'
// Custom expiration (in days)
expirationDays: 90Display Options
// Auto-show configuration
autoShow: true,
showDelay: 1500, // milliseconds
// Manual control
autoShow: falseStyling Variables
Customize the appearance using CSS custom properties:
:root {
--primary-color: #3b82f6;
--success-color: #10b981;
--danger-color: #ef4444;
--background: #ffffff;
--surface: #f8fafc;
--text-primary: #1f2937;
--border-radius: 8px;
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- iOS Safari 12+
- Android Chrome 60+
Accessibility Features
- Full keyboard navigation support
- Screen reader compatible
- ARIA labels and roles
- High contrast mode support
- Focus management
- Semantic HTML structure
GDPR Compliance
- Granular consent management
- Clear cookie descriptions
- Easy opt-out options
- Consent audit trail
- Data retention controls
- Privacy preference center
Performance
- Lightweight implementation (~15KB gzipped)
- Lazy loading of non-essential features
- Optimized animations
- Minimal DOM manipulation
- Efficient event handling
This interactive tabs cookie banner provides a comprehensive solution for cookie consent management with advanced customization options, smooth animations, and full GDPR compliance.
HTML
1570
lines
CSS
10
lines
JavaScript
31
lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Tabs Cookie Banner</title>
<style>
:root {
--primary-color: #3b82f6;
--primary-hover: #2563eb;
--secondary-color: #6b7280;
--success-color: #10b981;
--success-hover: #059669;
--warning-color: #f59e0b;
--warning-hover: #d97706;
--danger-color: #ef4444;
--danger-hover: #dc2626;
--background: #ffffff;
--surface: #f8fafc;
--surface-hover: #f1f5f9;
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: #e5e7eb;
--border-hover: #d1d5db;
--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: 8px;
--border-radius-lg: 12px;
--border-radius-xl: 16px;
--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);
}
* {
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;
}
.demo-container {
max-width: 1200px;
margin: 0 auto;
text-align: center;
color: white;
}
.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);
}
/* Interactive Tabs Cookie Banner */
.interactive-tabs-cookie-banner {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 480px;
max-width: calc(100vw - 4rem);
background: var(--background);
border-radius: var(--border-radius-xl);
box-shadow: var(--shadow-xl);
border: 1px solid var(--border-color);
transform: translateX(120%);
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10000;
backdrop-filter: blur(20px);
overflow: hidden;
}
.interactive-tabs-cookie-banner.show {
transform: translateX(0);
}
.banner-header {
padding: 1.5rem;
border-bottom: 1px solid var(--border-color);
background: linear-gradient(135deg, var(--surface) 0%, var(--background) 100%);
}
.banner-title {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.5rem;
}
.banner-icon {
width: 32px;
height: 32px;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
color: white;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);
}
}
.title-text {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
}
.banner-description {
color: var(--text-secondary);
font-size: 0.9rem;
line-height: 1.5;
}
.close-button {
position: absolute;
top: 1rem;
right: 1rem;
width: 32px;
height: 32px;
border: none;
background: var(--surface);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
transition: var(--transition-fast);
font-size: 1.2rem;
}
.close-button:hover {
background: var(--border-color);
color: var(--text-primary);
transform: scale(1.1);
}
/* Tab Navigation */
.tab-navigation {
display: flex;
background: var(--surface);
border-bottom: 1px solid var(--border-color);
overflow-x: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tab-navigation::-webkit-scrollbar {
display: none;
}
.tab-button {
flex: 1;
min-width: 120px;
padding: 1rem 0.75rem;
border: none;
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition-fast);
position: relative;
white-space: nowrap;
}
.tab-button.active {
color: var(--primary-color);
background: var(--background);
}
.tab-button::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background: var(--primary-color);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.tab-button.active::after {
transform: scaleX(1);
}
.tab-button:hover {
color: var(--primary-hover);
background: var(--surface-hover);
}
/* Tab Content */
.tab-content {
max-height: 400px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--border-color) transparent;
}
.tab-content::-webkit-scrollbar {
width: 6px;
}
.tab-content::-webkit-scrollbar-track {
background: transparent;
}
.tab-content::-webkit-scrollbar-thumb {
background: var(--border-color);
border-radius: 3px;
}
.tab-panel {
display: none;
padding: 1.5rem;
animation: fadeIn 0.3s ease;
}
.tab-panel.active {
display: block;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Cookie Category */
.cookie-category {
margin-bottom: 1.5rem;
padding: 1rem;
background: var(--surface);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
box-shadow: var(--shadow-md);
border-color: var(--border-hover);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-info {
flex: 1;
}
.category-title {
font-weight: 700;
font-size: 1rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.category-count {
font-size: 0.8rem;
color: var(--text-muted);
background: var(--background);
padding: 0.25rem 0.5rem;
border-radius: 12px;
display: inline-block;
}
.category-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
margin-bottom: 1rem;
}
/* Toggle Switch */
.toggle-switch {
position: relative;
width: 52px;
height: 28px;
background: var(--border-color);
border-radius: 14px;
cursor: pointer;
transition: var(--transition);
flex-shrink: 0;
}
.toggle-switch.active {
background: var(--success-color);
}
.toggle-switch.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.toggle-switch::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 24px;
height: 24px;
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);
}
/* Cookie Details */
.cookie-details {
margin-top: 1rem;
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: var(--background);
border-radius: var(--border-radius);
margin-bottom: 0.5rem;
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.detail-item:hover {
background: var(--surface-hover);
}
.detail-info {
flex: 1;
}
.detail-name {
font-weight: 600;
font-size: 0.9rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.detail-description {
font-size: 0.8rem;
color: var(--text-secondary);
line-height: 1.4;
}
.detail-toggle {
width: 40px;
height: 20px;
background: var(--border-color);
border-radius: 10px;
position: relative;
cursor: pointer;
transition: var(--transition);
}
.detail-toggle.active {
background: var(--primary-color);
}
.detail-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
background: white;
border-radius: 50%;
transition: var(--transition);
}
.detail-toggle.active::before {
transform: translateX(20px);
}
/* Action Buttons */
.banner-actions {
padding: 1.5rem;
border-top: 1px solid var(--border-color);
background: var(--surface);
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.action-button {
flex: 1;
min-width: 120px;
padding: 0.75rem 1rem;
border: none;
border-radius: var(--border-radius);
font-family: inherit;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.action-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
.action-button:hover::before {
left: 100%;
}
.btn-accept {
background: var(--success-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-accept:hover {
background: var(--success-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-reject {
background: var(--danger-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-reject:hover {
background: var(--danger-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-save {
background: var(--primary-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-save:hover {
background: var(--primary-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
/* Statistics Panel */
.stats-panel {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.stat-item {
text-align: center;
padding: 1rem;
background: var(--surface);
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;
}
/* Privacy Settings */
.privacy-setting {
margin-bottom: 1rem;
padding: 1rem;
background: var(--background);
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
}
.setting-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.setting-title {
font-weight: 600;
color: var(--text-primary);
}
.setting-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
}
/* Loading States */
.loading-dots {
display: inline-flex;
gap: 4px;
}
.loading-dots span {
width: 6px;
height: 6px;
background: currentColor;
border-radius: 50%;
animation: loading 1.4s infinite ease-in-out;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
@keyframes loading {
0%, 80%, 100% {
transform: scale(0.8);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
/* Success Animation */
.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;
}
}
/* Responsive Design */
@media (max-width: 768px) {
.interactive-tabs-cookie-banner {
bottom: 0;
right: 0;
left: 0;
width: 100%;
max-width: none;
border-radius: var(--border-radius-lg) var(--border-radius-lg) 0 0;
transform: translateY(100%);
}
.interactive-tabs-cookie-banner.show {
transform: translateY(0);
}
.tab-navigation {
overflow-x: auto;
}
.tab-button {
min-width: 100px;
font-size: 0.8rem;
}
.banner-actions {
flex-direction: column;
}
.action-button {
width: 100%;
min-width: auto;
}
.stats-panel {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-header {
padding: 1rem;
}
.tab-panel {
padding: 1rem;
}
.banner-actions {
padding: 1rem;
}
}
/* Animation Variants */
.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;
}
}
.bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes bounceIn {
0% {
transform: translateX(100%) scale(0.3);
opacity: 0;
}
50% {
transform: translateX(-10%) scale(1.05);
}
70% {
transform: translateX(5%) scale(0.98);
}
100% {
transform: translateX(0) scale(1);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Interactive Tabs Design</h1>
<p>Experience the power of tabbed navigation with detailed settings and advanced customization options</p>
<button class="demo-btn" onclick="showCookieBanner()">Show Cookie Banner</button>
</div>
<!-- Interactive Tabs Cookie Banner -->
<div id="interactiveTabsCookieBanner" class="interactive-tabs-cookie-banner">
<button class="close-button" onclick="closeBanner()" aria-label="Close banner">×</button>
<div class="banner-header">
<div class="banner-title">
<div class="banner-icon">🍪</div>
<div class="title-text">Cookie Preferences</div>
</div>
<div class="banner-description">
We use cookies to enhance your browsing experience and provide personalized content. Choose your preferences below.
</div>
</div>
<div class="tab-navigation">
<button class="tab-button active" data-tab="overview">Overview</button>
<button class="tab-button" data-tab="essential">Essential</button>
<button class="tab-button" data-tab="analytics">Analytics</button>
<button class="tab-button" data-tab="marketing">Marketing</button>
<button class="tab-button" data-tab="preferences">Preferences</button>
</div>
<div class="tab-content">
<!-- Overview Tab -->
<div id="overview" class="tab-panel active">
<div class="stats-panel">
<div class="stat-item">
<div class="stat-number">4</div>
<div class="stat-label">Categories</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">Cookie Types</div>
</div>
<div class="stat-item">
<div class="stat-number">365</div>
<div class="stat-label">Days Stored</div>
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Essential Cookies <span class="category-count">Always Active</span></div>
</div>
<div class="toggle-switch active disabled"></div>
</div>
<div class="category-description">
These cookies are necessary for the website to function and cannot be switched off.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Analytics Cookies <span class="category-count">3 cookies</span></div>
</div>
<div class="toggle-switch" data-category="analytics"></div>
</div>
<div class="category-description">
Help us understand how visitors interact with our website by collecting information anonymously.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<div class="category-info">
<div class="category-title">Marketing Cookies <span class="category-count">5 cookies</span></div>
</div>
<div class="toggle-switch" data-category="marketing"></div>
</div>
<div class="category-description">
Used to deliver more relevant advertisements based on your browsing behavior.
</div>
</div>
</div>
<!-- Essential Tab -->
<div id="essential" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Session Cookie</div>
<div class="detail-description">Maintains your session while browsing</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Security Token</div>
<div class="detail-description">Protects against cross-site request forgery</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Language Preference</div>
<div class="detail-description">Remembers your selected language</div>
</div>
<div class="detail-toggle active"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Cookie Consent</div>
<div class="detail-description">Stores your cookie preferences</div>
</div>
<div class="detail-toggle active"></div>
</div>
</div>
</div>
<!-- Analytics Tab -->
<div id="analytics" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Google Analytics</div>
<div class="detail-description">Tracks website usage and performance metrics</div>
</div>
<div class="detail-toggle" data-cookie="ga"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Hotjar</div>
<div class="detail-description">Records user interactions for UX improvements</div>
</div>
<div class="detail-toggle" data-cookie="hotjar"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Performance Monitoring</div>
<div class="detail-description">Monitors site speed and performance</div>
</div>
<div class="detail-toggle" data-cookie="performance"></div>
</div>
</div>
</div>
<!-- Marketing Tab -->
<div id="marketing" class="tab-panel">
<div class="cookie-details">
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Facebook Pixel</div>
<div class="detail-description">Tracks conversions and builds audiences</div>
</div>
<div class="detail-toggle" data-cookie="facebook"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Google Ads</div>
<div class="detail-description">Enables remarketing and ad personalization</div>
</div>
<div class="detail-toggle" data-cookie="google-ads"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">LinkedIn Insight</div>
<div class="detail-description">Tracks professional audience engagement</div>
</div>
<div class="detail-toggle" data-cookie="linkedin"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Twitter Analytics</div>
<div class="detail-description">Measures social media campaign effectiveness</div>
</div>
<div class="detail-toggle" data-cookie="twitter"></div>
</div>
<div class="detail-item">
<div class="detail-info">
<div class="detail-name">Affiliate Tracking</div>
<div class="detail-description">Tracks referrals and commission attribution</div>
</div>
<div class="detail-toggle" data-cookie="affiliate"></div>
</div>
</div>
</div>
<!-- Preferences Tab -->
<div id="preferences" class="tab-panel">
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Data Retention Period</div>
<select class="setting-control">
<option value="30">30 days</option>
<option value="90">90 days</option>
<option value="365" selected>1 year</option>
<option value="730">2 years</option>
</select>
</div>
<div class="setting-description">
How long we keep your data before automatic deletion.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Data Sharing</div>
<div class="toggle-switch" data-setting="sharing"></div>
</div>
<div class="setting-description">
Allow sharing anonymized data with trusted partners for research.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Personalized Experience</div>
<div class="toggle-switch active" data-setting="personalization"></div>
</div>
<div class="setting-description">
Enable personalized content and recommendations based on your activity.
</div>
</div>
<div class="privacy-setting">
<div class="setting-header">
<div class="setting-title">Email Notifications</div>
<div class="toggle-switch" data-setting="notifications"></div>
</div>
<div class="setting-description">
Receive updates about privacy policy changes and new features.
</div>
</div>
</div>
</div>
<div class="banner-actions">
<button class="action-button btn-accept" onclick="acceptAllCookies()">Accept All</button>
<button class="action-button btn-reject" onclick="rejectOptionalCookies()">Reject Optional</button>
<button class="action-button btn-save" onclick="saveCustomSettings()">Save Settings</button>
</div>
</div>
<script>
class InteractiveTabsCookieBanner {
constructor(options = {}) {
this.options = {
autoShow: true,
showDelay: 1500,
storageKey: 'interactive_tabs_cookie_consent',
expirationDays: 365,
enableAnimations: true,
animationType: 'slide', // 'slide', 'bounce', 'fade'
onAccept: null,
onReject: null,
onSave: null,
onClose: null,
...options
};
this.banner = document.getElementById('interactiveTabsCookieBanner');
this.consent = this.getStoredConsent();
this.isVisible = false;
this.activeTab = 'overview';
this.initialize();
}
initialize() {
if (this.options.autoShow && !this.consent) {
setTimeout(() => this.show(), this.options.showDelay);
}
this.setupEventListeners();
this.loadSettings();
this.setupAnimationType();
}
setupEventListeners() {
// Tab navigation
document.querySelectorAll('.tab-button').forEach(button => {
button.addEventListener('click', () => {
this.switchTab(button.dataset.tab);
});
});
// Toggle switches
document.querySelectorAll('.toggle-switch:not(.disabled)').forEach(toggle => {
toggle.addEventListener('click', () => {
this.toggleSwitch(toggle);
});
});
// Detail toggles
document.querySelectorAll('.detail-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
this.toggleDetailSwitch(toggle);
});
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (this.isVisible) {
this.handleKeyboardNavigation(e);
}
});
// Button hover effects
document.querySelectorAll('.action-button').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.createRipple(btn);
});
});
}
setupAnimationType() {
const animationClasses = {
slide: 'slide-in-right',
bounce: 'bounce-in',
fade: 'fade-in'
};
const animationClass = animationClasses[this.options.animationType];
if (animationClass) {
this.banner.classList.add(animationClass);
}
}
switchTab(tabName) {
// Update active tab button
document.querySelectorAll('.tab-button').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`[data-tab="\${tabName}"]`).classList.add('active');
// Update active tab panel
document.querySelectorAll('.tab-panel').forEach(panel => {
panel.classList.remove('active');
});
document.getElementById(tabName).classList.add('active');
this.activeTab = tabName;
if (this.options.enableAnimations) {
this.animateTabSwitch(tabName);
}
}
animateTabSwitch(tabName) {
const panel = document.getElementById(tabName);
const elements = panel.querySelectorAll('.cookie-category, .detail-item, .privacy-setting, .stat-item');
elements.forEach((el, index) => {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
setTimeout(() => {
el.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, index * 50);
});
}
toggleSwitch(toggle) {
toggle.classList.toggle('active');
if (this.options.enableAnimations) {
this.animateToggle(toggle);
}
// Update category state
const category = toggle.dataset.category;
if (category) {
this.updateCategoryState(category, toggle.classList.contains('active'));
}
}
toggleDetailSwitch(toggle) {
toggle.classList.toggle('active');
if (this.options.enableAnimations) {
this.animateToggle(toggle);
}
// Update individual cookie state
const cookie = toggle.dataset.cookie;
if (cookie) {
this.updateCookieState(cookie, toggle.classList.contains('active'));
}
}
animateToggle(toggle) {
toggle.style.transform = 'scale(0.9)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
// Add pulse effect
const color = toggle.classList.contains('active') ?
'rgba(16, 185, 129, 0.2)' : 'rgba(107, 114, 128, 0.2)';
toggle.style.boxShadow = `0 0 0 8px \${color}`;
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
updateCategoryState(category, enabled) {
// Update all related detail toggles
const detailToggles = document.querySelectorAll(`[data-cookie^="\${category}"]`);
detailToggles.forEach(toggle => {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
});
}
updateCookieState(cookie, enabled) {
// Update parent category if all cookies are enabled/disabled
this.updateParentCategoryState();
}
updateParentCategoryState() {
const categories = ['analytics', 'marketing'];
categories.forEach(category => {
const categoryToggle = document.querySelector(`[data-category="\${category}"]`);
const cookieToggles = document.querySelectorAll(`[data-cookie*="\${category}"]`);
if (categoryToggle && cookieToggles.length > 0) {
const allEnabled = Array.from(cookieToggles).every(toggle =>
toggle.classList.contains('active'));
const anyEnabled = Array.from(cookieToggles).some(toggle =>
toggle.classList.contains('active'));
if (allEnabled) {
categoryToggle.classList.add('active');
} else {
categoryToggle.classList.remove('active');
}
}
});
}
handleKeyboardNavigation(e) {
switch (e.key) {
case 'Escape':
this.close();
break;
case 'Tab':
// Let browser handle tab navigation
break;
case 'ArrowLeft':
case 'ArrowRight':
if (e.target.classList.contains('tab-button')) {
this.navigateTabs(e.key === 'ArrowRight' ? 1 : -1);
e.preventDefault();
}
break;
}
}
navigateTabs(direction) {
const tabs = Array.from(document.querySelectorAll('.tab-button'));
const currentIndex = tabs.findIndex(tab => tab.classList.contains('active'));
const newIndex = (currentIndex + direction + tabs.length) % tabs.length;
this.switchTab(tabs[newIndex].dataset.tab);
tabs[newIndex].focus();
}
createRipple(button) {
if (!this.options.enableAnimations) 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);
}
show() {
this.banner.classList.add('show');
this.isVisible = true;
if (this.options.enableAnimations) {
this.animateEntrance();
}
}
hide() {
this.banner.classList.remove('show');
this.isVisible = false;
}
close() {
this.hide();
if (this.options.onClose) {
this.options.onClose();
}
}
animateEntrance() {
const elements = [
this.banner.querySelector('.banner-header'),
this.banner.querySelector('.tab-navigation'),
this.banner.querySelector('.tab-content'),
this.banner.querySelector('.banner-actions')
];
elements.forEach((el, index) => {
if (el) {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
setTimeout(() => {
el.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
el.style.opacity = '1';
el.style.transform = 'translateY(0)';
}, index * 100);
}
});
}
acceptAllCookies() {
const consent = {
essential: true,
analytics: true,
marketing: true,
functional: true,
timestamp: Date.now()
};
this.saveConsent(consent);
this.showSuccessAnimation();
setTimeout(() => {
this.hide();
}, 1500);
if (this.options.onAccept) {
this.options.onAccept(consent);
}
}
rejectOptionalCookies() {
const consent = {
essential: true,
analytics: false,
marketing: false,
functional: false,
timestamp: Date.now()
};
this.saveConsent(consent);
this.hide();
if (this.options.onReject) {
this.options.onReject(consent);
}
}
saveCustomSettings() {
const toggles = document.querySelectorAll('.toggle-switch, .detail-toggle');
const consent = { timestamp: Date.now() };
// Get category states
consent.essential = true; // Always true
consent.analytics = document.querySelector('[data-category="analytics"]')?.classList.contains('active') || false;
consent.marketing = document.querySelector('[data-category="marketing"]')?.classList.contains('active') || false;
consent.functional = true; // Assume functional if not explicitly set
// Get individual cookie states
const cookieStates = {};
document.querySelectorAll('[data-cookie]').forEach(toggle => {
const cookie = toggle.dataset.cookie;
cookieStates[cookie] = toggle.classList.contains('active');
});
consent.cookies = cookieStates;
// Get preference settings
const settings = {};
document.querySelectorAll('[data-setting]').forEach(toggle => {
const setting = toggle.dataset.setting;
settings[setting] = toggle.classList.contains('active');
});
consent.settings = settings;
this.saveConsent(consent);
this.showSuccessAnimation();
setTimeout(() => {
this.hide();
}, 1500);
if (this.options.onSave) {
this.options.onSave(consent);
}
}
showSuccessAnimation() {
if (!this.options.enableAnimations) return;
const saveBtn = this.banner.querySelector('.btn-save');
if (saveBtn) {
saveBtn.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>
Saved
`;
saveBtn.style.background = 'var(--success-color)';
}
}
loadSettings() {
if (this.consent) {
// Load category states
Object.entries(this.consent).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');
}
}
}
});
// Load individual cookie states
if (this.consent.cookies) {
Object.entries(this.consent.cookies).forEach(([cookie, enabled]) => {
const toggle = document.querySelector(`[data-cookie="\${cookie}"]`);
if (toggle) {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
// Load preference settings
if (this.consent.settings) {
Object.entries(this.consent.settings).forEach(([setting, enabled]) => {
const toggle = document.querySelector(`[data-setting="\${setting}"]`);
if (toggle) {
if (enabled) {
toggle.classList.add('active');
} else {
toggle.classList.remove('active');
}
}
});
}
}
}
saveConsent(consent) {
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + this.options.expirationDays);
const consentData = {
...consent,
expiration: expirationDate.getTime()
};
localStorage.setItem(this.options.storageKey, JSON.stringify(consentData));
this.consent = consent;
}
getStoredConsent() {
try {
const stored = localStorage.getItem(this.options.storageKey);
if (stored) {
const data = JSON.parse(stored);
if (data.expiration && Date.now() < data.expiration) {
return data;
} else {
localStorage.removeItem(this.options.storageKey);
}
}
} catch (e) {
console.error('Error reading cookie consent:', e);
}
return null;
}
reset() {
localStorage.removeItem(this.options.storageKey);
this.consent = null;
this.show();
}
getConsent() {
return this.consent;
}
setAnimationType(type) {
this.options.animationType = type;
this.setupAnimationType();
}
enableAnimations(enabled) {
this.options.enableAnimations = enabled;
}
updateTheme(theme) {
const themes = {
light: {
'--background': '#ffffff',
'--surface': '#f8fafc',
'--text-primary': '#1f2937',
'--text-secondary': '#6b7280'
},
dark: {
'--background': '#1f2937',
'--surface': '#374151',
'--text-primary': '#f9fafb',
'--text-secondary': '#d1d5db'
}
};
if (themes[theme]) {
Object.entries(themes[theme]).forEach(([property, value]) => {
document.documentElement.style.setProperty(property, value);
});
}
}
}
// Add ripple animation CSS
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Initialize the banner
const cookieBanner = new InteractiveTabsCookieBanner({
animationType: 'slide',
enableAnimations: true,
onAccept: (consent) => {
console.log('Cookies accepted:', consent);
// Initialize analytics, marketing scripts, etc.
},
onReject: (consent) => {
console.log('Optional cookies rejected:', consent);
// Load only essential scripts
},
onSave: (consent) => {
console.log('Custom settings saved:', consent);
// Load scripts based on user preferences
},
onClose: () => {
console.log('Banner closed without action');
}
});
// Global functions for demo
function showCookieBanner() {
cookieBanner.reset();
}
function closeBanner() {
cookieBanner.close();
}
function acceptAllCookies() {
cookieBanner.acceptAllCookies();
}
function rejectOptionalCookies() {
cookieBanner.rejectOptionalCookies();
}
function saveCustomSettings() {
cookieBanner.saveCustomSettings();
}
</script>
</body>
</html>