Bottom Slide-in Cookie Consent Banner
A sleek bottom slide-in cookie consent banner with smooth transitions, progressive disclosure, and elegant animation effects
Responsive Design
Yes
Dark Mode Support
No
lines
1084
Browser Compatibility
No
Live Preview
Interact with the component without leaving the page.
Bottom Slide-in Cookie Consent Banner
A beautifully designed bottom slide-in cookie consent banner that appears with smooth transitions and elegant animations. Features progressive disclosure, customizable settings, and a modern design that enhances user experience while ensuring GDPR compliance.
Features
- Smooth Slide Animation: Elegant bottom slide-in transition with easing curves
- Progressive Disclosure: Expandable sections for detailed cookie information
- Smooth Transitions: Fluid animations for all interactive elements
- Modern Typography: Clean, readable fonts with proper hierarchy
- GDPR Compliant: Complete consent management with granular controls
- Accessibility First: Full keyboard navigation and screen reader support
- Responsive Design: Adapts beautifully to all screen sizes and orientations
- Customizable Styling: Easy theme customization with CSS variables
- 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>Bottom Slide Cookie Banner</title>
<style>
:root {
--primary-color: #4f46e5;
--primary-hover: #4338ca;
--secondary-color: #6b7280;
--success-color: #059669;
--success-hover: #047857;
--danger-color: #dc2626;
--danger-hover: #b91c1c;
--background: #ffffff;
--surface: #f9fafb;
--text-primary: #111827;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: #e5e7eb;
--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);
--border-radius: 8px;
--border-radius-lg: 12px;
--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);
--slide-distance: 100%;
}
* {
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);
}.bottom-slide-cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--background);
border-top: 1px solid var(--border-color);
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1), 0 -2px 4px -1px rgba(0, 0, 0, 0.06);
transform: translateY(var(--slide-distance));
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10000;
backdrop-filter: blur(20px);
}
.bottom-slide-cookie-banner.show {
transform: translateY(0);
}
.banner-content {
max-width: 1200px;
margin: 0 auto;
padding: 1.5rem;
}
.banner-header {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1rem;
}
.banner-icon {
width: 48px;
height: 48px;
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.5rem;
color: white;
flex-shrink: 0;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.4);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 0 10px rgba(79, 70, 229, 0);
}
}
.banner-text {
flex: 1;
}
.banner-title {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
.banner-description {
color: var(--text-secondary);
font-size: 0.95rem;
line-height: 1.6;
}
.cookie-link {
color: var(--primary-color);
text-decoration: none;
font-weight: 600;
transition: var(--transition-fast);
position: relative;
}
.cookie-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: var(--primary-color);
transition: width 0.3s ease;
}
.cookie-link:hover {
color: var(--primary-hover);
}
.cookie-link:hover::after {
width: 100%;
}
.banner-actions {
display: flex;
gap: 0.75rem;
align-items: center;
flex-wrap: wrap;
margin-top: 1rem;
}.slide-btn {
padding: 0.75rem 1.5rem;
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;
min-width: 120px;
}
.slide-btn::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;
}
.slide-btn: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-decline {
background: var(--danger-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-decline:hover {
background: var(--danger-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-customize {
background: var(--surface);
color: var(--text-primary);
border: 1px solid var(--border-color);
box-shadow: var(--shadow-sm);
}
.btn-customize:hover {
background: var(--border-color);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.btn-expand {
background: transparent;
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 0.5rem 1rem;
font-size: 0.8rem;
}
.btn-expand:hover {
background: var(--primary-color);
color: white;
}.expandable-details {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), padding 0.4s ease;
background: var(--surface);
border-radius: var(--border-radius);
margin-top: 1rem;
}
.expandable-details.expanded {
max-height: 400px;
padding: 1.5rem;
border: 1px solid var(--border-color);
}
.details-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
.cookie-category {
background: var(--background);
padding: 1rem;
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
box-shadow: var(--shadow-md);
transform: translateY(-1px);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-title {
font-weight: 700;
font-size: 1rem;
color: var(--text-primary);
}
.category-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
}.slide-toggle {
position: relative;
width: 48px;
height: 24px;
background: var(--border-color);
border-radius: 12px;
cursor: pointer;
transition: var(--transition);
}
.slide-toggle.active {
background: var(--success-color);
}
.slide-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: var(--transition);
box-shadow: var(--shadow-sm);
}
.slide-toggle.active::before {
transform: translateX(24px);
}
.slide-toggle:hover {
transform: scale(1.05);
}.progress-indicator {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
background: var(--primary-color);
width: 0;
transition: width 0.3s ease;
}
.banner-content:hover .progress-indicator {
width: 100%;
}.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-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;
}
}@media (max-width: 768px) {
.banner-header {
flex-direction: column;
text-align: center;
}
.banner-actions {
justify-content: center;
flex-direction: column;
}
.slide-btn {
width: 100%;
min-width: auto;
}
.details-grid {
grid-template-columns: 1fr;
}
.banner-content {
padding: 1rem;
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-content {
padding: 0.75rem;
}
.banner-title {
font-size: 1.1rem;
}
.banner-description {
font-size: 0.9rem;
}
}.slide-in-left {
transform: translateX(-100%);
}
.slide-in-right {
transform: translateX(100%);
}
.slide-in-fade {
transform: translateY(100%) scale(0.9);
opacity: 0;
}
.slide-in-fade.show {
transform: translateY(0) scale(1);
opacity: 1;
}.bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes bounceIn {
0% {
transform: translateY(100%) scale(0.3);
opacity: 0;
}
50% {
transform: translateY(-10%) scale(1.05);
}
70% {
transform: translateY(5%) scale(0.98);
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Smooth Slide Design</h1>
<p>Experience the elegance of smooth slide transitions with progressive disclosure and modern interactions</p>
<button class="demo-btn" onclick="showCookieBanner()">Show Cookie Banner</button>
</div>
<div id="bottomSlideCookieBanner" class="bottom-slide-cookie-banner">
<div class="progress-indicator"></div>
<div class="banner-content">
<div class="banner-header">
<div class="banner-icon">🍪</div>
<div class="banner-text">
<div class="banner-title">Cookie Preferences</div>
<div class="banner-description">
We use cookies to enhance your browsing experience and provide personalized content.
<a href="#" class="cookie-link">Privacy Policy</a> |
<a href="#" class="cookie-link">Cookie Policy</a>
</div>
</div>
</div>
<div class="banner-actions">
<button class="slide-btn btn-accept" onclick="acceptCookies()">Accept All</button>
<button class="slide-btn btn-decline" onclick="declineCookies()">Decline</button>
<button class="slide-btn btn-customize" onclick="openCustomization()">Customize</button>
<button class="slide-btn btn-expand" onclick="toggleDetails()">Learn More</button>
</div>
<div id="expandableDetails" class="expandable-details">
<div class="details-grid">
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Essential Cookies</span>
<div class="slide-toggle active" data-category="essential"></div>
</div>
<div class="category-description">
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Analytics Cookies</span>
<div class="slide-toggle" data-category="analytics"></div>
</div>
<div class="category-description">
These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Marketing Cookies</span>
<div class="slide-toggle" data-category="marketing"></div>
</div>
<div class="category-description">
These cookies are used to deliver advertisements more relevant to you and your interests based on your browsing behavior.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Functional Cookies</span>
<div class="slide-toggle" data-category="functional"></div>
</div>
<div class="category-description">
These cookies enable enhanced functionality and personalization, such as remembering your preferences and settings.
</div>
</div>
</div>
</div>
</div>
</div>
<script>
class BottomSlideCookieBanner {
constructor(options = {}) {
this.options = {
autoShow: true,
showDelay: 1500,
storageKey: 'bottom_slide_cookie_consent',
expirationDays: 365,
enableAnimations: true,
slideDirection: 'bottom',
animationType: 'slide', // 'slide', 'fade', 'bounce'
progressiveDisclosure: true,
onAccept: null,
onDecline: null,
onCustomize: null,
...options
};
this.banner = document.getElementById('bottomSlideCookieBanner');
this.expandableDetails = document.getElementById('expandableDetails');
this.consent = this.getStoredConsent();
this.isVisible = false;
this.isExpanded = false;
this.init();
}
init() {
if (this.options.autoShow && !this.consent) {
setTimeout(() => this.show(), this.options.showDelay);
}
this.setupEventListeners();
this.loadConfiguration();
this.setupAnimationType();
}
setupEventListeners() {
document.querySelectorAll('.slide-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
if (toggle.dataset.category !== 'essential') {
toggle.classList.toggle('active');
this.animateToggle(toggle);
}
});
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && this.isExpanded) {
this.toggleDetails();
}
});
document.querySelectorAll('.slide-btn').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.createRipple(btn);
});
});
this.banner.addEventListener('mouseenter', () => {
if (this.isVisible) {
this.enhanceProgressIndicator();
}
});
this.banner.addEventListener('mouseleave', () => {
if (this.isVisible) {
this.resetProgressIndicator();
}
});
}
setupAnimationType() {
const animationClasses = {
slide: '',
fade: 'slide-in-fade',
bounce: 'bounce-in'
};
const animationClass = animationClasses[this.options.animationType];
if (animationClass) {
this.banner.classList.add(animationClass);
}
}
animateToggle(toggle) {
if (!this.options.enableAnimations) return;
toggle.style.transform = 'scale(0.9)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
toggle.style.boxShadow = '0 0 0 8px rgba(5, 150, 105, 0.2)';
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
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);
}
enhanceProgressIndicator() {
if (!this.options.enableAnimations) return;
const indicator = this.banner.querySelector('.progress-indicator');
if (indicator) {
indicator.style.background = 'linear-gradient(90deg, var(--primary-color), var(--success-color))';
indicator.style.height = '4px';
}
}
resetProgressIndicator() {
if (!this.options.enableAnimations) return;
const indicator = this.banner.querySelector('.progress-indicator');
if (indicator) {
indicator.style.background = 'var(--primary-color)';
indicator.style.height = '3px';
}
}
show() {
this.banner.classList.add('show');
this.isVisible = true;
if (this.options.enableAnimations) {
this.animateEntrance();
}
}
hide() {
this.banner.classList.remove('show');
this.isVisible = false;
this.isExpanded = false;
this.expandableDetails.classList.remove('expanded');
}
animateEntrance() {
const elements = [
this.banner.querySelector('.banner-icon'),
this.banner.querySelector('.banner-title'),
this.banner.querySelector('.banner-description'),
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);
}
});
}
toggleDetails() {
this.isExpanded = !this.isExpanded;
if (this.isExpanded) {
this.expandableDetails.classList.add('expanded');
if (this.options.enableAnimations) {
this.animateDetailsExpansion();
}
} else {
this.expandableDetails.classList.remove('expanded');
}
const expandBtn = this.banner.querySelector('.btn-expand');
if (expandBtn) {
expandBtn.textContent = this.isExpanded ? 'Show Less' : 'Learn More';
}
}
animateDetailsExpansion() {
const categories = this.expandableDetails.querySelectorAll('.cookie-category');
categories.forEach((category, index) => {
category.style.opacity = '0';
category.style.transform = 'translateY(20px)';
setTimeout(() => {
category.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
category.style.opacity = '1';
category.style.transform = 'translateY(0)';
}, index * 100);
});
}
accept() {
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);
}
}
decline() {
const consent = {
essential: true,
analytics: false,
marketing: false,
functional: false,
timestamp: Date.now()
};
this.saveConsent(consent);
this.hide();
if (this.options.onDecline) {
this.options.onDecline(consent);
}
}
showSuccessAnimation() {
if (!this.options.enableAnimations) return;
const acceptBtn = this.banner.querySelector('.btn-accept');
if (acceptBtn) {
acceptBtn.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>
Accepted
`;
acceptBtn.style.background = 'var(--success-color)';
}
}
customize() {
this.toggleDetails();
if (this.options.onCustomize) {
this.options.onCustomize();
}
}
saveCustomization() {
const toggles = document.querySelectorAll('.slide-toggle');
const consent = { timestamp: Date.now() };
toggles.forEach(toggle => {
const category = toggle.dataset.category;
consent[category] = toggle.classList.contains('active');
});
this.saveConsent(consent);
this.hide();
if (this.options.onCustomize) {
this.options.onCustomize(consent);
}
}
loadConfiguration() {
if (this.consent) {
document.querySelectorAll('.slide-toggle').forEach(toggle => {
const category = toggle.dataset.category;
if (this.consent[category]) {
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;
}
setSlideDirection(direction) {
this.options.slideDirection = direction;
this.setupSlideDirection();
}
setupSlideDirection() {
const directions = {
bottom: 'translateY(100%)',
top: 'translateY(-100%)',
left: 'translateX(-100%)',
right: 'translateX(100%)'
};
const transform = directions[this.options.slideDirection] || directions.bottom;
document.documentElement.style.setProperty('--slide-distance', transform);
}
setAnimationType(type) {
this.options.animationType = type;
this.setupAnimationType();
}
enableAnimations(enabled) {
this.options.enableAnimations = enabled;
}
updateTheme(theme) {
const themes = {
light: {
'--background': '#ffffff',
'--surface': '#f9fafb',
'--text-primary': '#111827',
'--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);
});
}
}
}
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
const cookieBanner = new BottomSlideCookieBanner({
slideDirection: 'bottom',
animationType: 'slide',
enableAnimations: true,
progressiveDisclosure: true,
onAccept: (consent) => {
console.log('Cookies accepted:', consent);
},
onDecline: (consent) => {
console.log('Cookies declined:', consent);
},
onCustomize: (consent) => {
console.log('Custom configuration saved:', consent);
}
});
function showCookieBanner() {
cookieBanner.reset();
}
function acceptCookies() {
cookieBanner.accept();
}
function declineCookies() {
cookieBanner.decline();
}
function openCustomization() {
cookieBanner.customize();
}
function toggleDetails() {
cookieBanner.toggleDetails();
}
</script>
</body>
</html>
Usage
Basic Implementation
const cookieBanner = new BottomSlideCookieBanner();
const cookieBanner = new BottomSlideCookieBanner({
autoShow: true,
showDelay: 2000,
storageKey: 'my_cookie_consent',
expirationDays: 180,
enableAnimations: true,
slideDirection: 'bottom',
animationType: 'slide',
progressiveDisclosure: true,
onAccept: (consent) => {
console.log('User accepted cookies:', consent);
if (consent.analytics) {
loadGoogleAnalytics();
}
if (consent.marketing) {
loadMarketingPixels();
}
},
onDecline: (consent) => {
console.log('User declined cookies:', consent);
},
onCustomize: (consent) => {
console.log('User saved custom configuration:', consent);
}
});
Advanced Configuration
const advancedBanner = new BottomSlideCookieBanner({
autoShow: false, // Manual control
showDelay: 0,
storageKey: 'advanced_consent',
expirationDays: 90,
enableAnimations: true,
slideDirection: 'bottom',
animationType: 'bounce',
progressiveDisclosure: true,
onAccept: (consent) => {
initializeAdvancedTracking(consent);
},
onDecline: (consent) => {
initializeEssentialOnly();
},
onCustomize: (consent) => {
loadScriptsBasedOnConsent(consent);
}
});
function changeSlideDirection(direction) {
advancedBanner.setSlideDirection(direction);
}
function changeAnimationType(type) {
advancedBanner.setAnimationType(type);
}
function toggleAnimations(enabled) {
advancedBanner.enableAnimations(enabled);
}
function switchTheme(theme) {
advancedBanner.updateTheme(theme);
}
function showConsentBanner() {
advancedBanner.show();
}
function checkConsentStatus() {
const consent = advancedBanner.getConsent();
if (consent) {
console.log('Current consent:', consent);
} else {
console.log('No consent given yet');
}
}
API Methods
Core Methods
show()- Display the cookie bannerhide()- Hide the cookie banneraccept()- Accept all cookies and hide bannerdecline()- Decline optional cookies and hide bannerreset()- Clear stored consent and show banner again
Configuration Management
toggleDetails()- Toggle expandable details sectioncustomize()- Open customization interfacesaveCustomization()- Save current configurationloadConfiguration()- Load and apply stored configuration
Data Management
getConsent()- Get current consent objectsaveConsent(consent)- Save consent to storagegetStoredConsent()- Retrieve consent from storage
Customization
setSlideDirection(direction)- Change slide direction (‘bottom’, ‘top’, ‘left’, ‘right’)setAnimationType(type)- Change animation type (‘slide’, ‘fade’, ‘bounce’)enableAnimations(enabled)- Enable/disable animationsupdateTheme(theme)- Switch between light/dark themescreateRipple(button)- Create ripple effects on buttons
Customization Options
Visual Customization
- Color Schemes: Modify CSS custom properties for different color themes
- Animation Speed: Adjust transition durations and animation timings
- Slide Effects: Customize slide directions and animation types
- Typography: Change font families, sizes, and weights
Functional Configuration
- Auto Display: Control automatic banner appearance
- Storage Duration: Set cookie consent expiration period
- Delay Settings: Configure show/hide timing
- Callback Functions: Custom handlers for user actions
Accessibility Features
- Keyboard Navigation: Full keyboard support with focus indicators
- Screen Reader Support: Proper ARIA labels and descriptions
- High Contrast: Enhanced visibility for accessibility
- Progressive Disclosure: Expandable sections for detailed information
Browser Compatibility
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- Mobile browsers (iOS Safari 12+, Chrome Mobile 60+)
License
MIT License - free to use in personal and commercial projects.
HTML
1052
lines
JavaScript
32
lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bottom Slide Cookie Banner</title>
<style>
:root {
--primary-color: #4f46e5;
--primary-hover: #4338ca;
--secondary-color: #6b7280;
--success-color: #059669;
--success-hover: #047857;
--danger-color: #dc2626;
--danger-hover: #b91c1c;
--background: #ffffff;
--surface: #f9fafb;
--text-primary: #111827;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
--border-color: #e5e7eb;
--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);
--border-radius: 8px;
--border-radius-lg: 12px;
--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);
--slide-distance: 100%;
}
* {
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);
}.bottom-slide-cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--background);
border-top: 1px solid var(--border-color);
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1), 0 -2px 4px -1px rgba(0, 0, 0, 0.06);
transform: translateY(var(--slide-distance));
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10000;
backdrop-filter: blur(20px);
}
.bottom-slide-cookie-banner.show {
transform: translateY(0);
}
.banner-content {
max-width: 1200px;
margin: 0 auto;
padding: 1.5rem;
}
.banner-header {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1rem;
}
.banner-icon {
width: 48px;
height: 48px;
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.5rem;
color: white;
flex-shrink: 0;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.4);
}
50% {
transform: scale(1.05);
box-shadow: 0 0 0 10px rgba(79, 70, 229, 0);
}
}
.banner-text {
flex: 1;
}
.banner-title {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
.banner-description {
color: var(--text-secondary);
font-size: 0.95rem;
line-height: 1.6;
}
.cookie-link {
color: var(--primary-color);
text-decoration: none;
font-weight: 600;
transition: var(--transition-fast);
position: relative;
}
.cookie-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: var(--primary-color);
transition: width 0.3s ease;
}
.cookie-link:hover {
color: var(--primary-hover);
}
.cookie-link:hover::after {
width: 100%;
}
.banner-actions {
display: flex;
gap: 0.75rem;
align-items: center;
flex-wrap: wrap;
margin-top: 1rem;
}.slide-btn {
padding: 0.75rem 1.5rem;
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;
min-width: 120px;
}
.slide-btn::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;
}
.slide-btn: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-decline {
background: var(--danger-color);
color: white;
box-shadow: var(--shadow-md);
}
.btn-decline:hover {
background: var(--danger-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-customize {
background: var(--surface);
color: var(--text-primary);
border: 1px solid var(--border-color);
box-shadow: var(--shadow-sm);
}
.btn-customize:hover {
background: var(--border-color);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.btn-expand {
background: transparent;
color: var(--primary-color);
border: 1px solid var(--primary-color);
padding: 0.5rem 1rem;
font-size: 0.8rem;
}
.btn-expand:hover {
background: var(--primary-color);
color: white;
}.expandable-details {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), padding 0.4s ease;
background: var(--surface);
border-radius: var(--border-radius);
margin-top: 1rem;
}
.expandable-details.expanded {
max-height: 400px;
padding: 1.5rem;
border: 1px solid var(--border-color);
}
.details-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
.cookie-category {
background: var(--background);
padding: 1rem;
border-radius: var(--border-radius);
border: 1px solid var(--border-color);
transition: var(--transition-fast);
}
.cookie-category:hover {
box-shadow: var(--shadow-md);
transform: translateY(-1px);
}
.category-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.category-title {
font-weight: 700;
font-size: 1rem;
color: var(--text-primary);
}
.category-description {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.5;
}.slide-toggle {
position: relative;
width: 48px;
height: 24px;
background: var(--border-color);
border-radius: 12px;
cursor: pointer;
transition: var(--transition);
}
.slide-toggle.active {
background: var(--success-color);
}
.slide-toggle::before {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: var(--transition);
box-shadow: var(--shadow-sm);
}
.slide-toggle.active::before {
transform: translateX(24px);
}
.slide-toggle:hover {
transform: scale(1.05);
}.progress-indicator {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
background: var(--primary-color);
width: 0;
transition: width 0.3s ease;
}
.banner-content:hover .progress-indicator {
width: 100%;
}.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-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;
}
}@media (max-width: 768px) {
.banner-header {
flex-direction: column;
text-align: center;
}
.banner-actions {
justify-content: center;
flex-direction: column;
}
.slide-btn {
width: 100%;
min-width: auto;
}
.details-grid {
grid-template-columns: 1fr;
}
.banner-content {
padding: 1rem;
}
}
@media (max-width: 480px) {
body {
padding: 1rem;
}
.demo-container h1 {
font-size: 2rem;
}
.banner-content {
padding: 0.75rem;
}
.banner-title {
font-size: 1.1rem;
}
.banner-description {
font-size: 0.9rem;
}
}.slide-in-left {
transform: translateX(-100%);
}
.slide-in-right {
transform: translateX(100%);
}
.slide-in-fade {
transform: translateY(100%) scale(0.9);
opacity: 0;
}
.slide-in-fade.show {
transform: translateY(0) scale(1);
opacity: 1;
}.bounce-in {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes bounceIn {
0% {
transform: translateY(100%) scale(0.3);
opacity: 0;
}
50% {
transform: translateY(-10%) scale(1.05);
}
70% {
transform: translateY(5%) scale(0.98);
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="demo-container">
<h1>Smooth Slide Design</h1>
<p>Experience the elegance of smooth slide transitions with progressive disclosure and modern interactions</p>
<button class="demo-btn" onclick="showCookieBanner()">Show Cookie Banner</button>
</div>
<div id="bottomSlideCookieBanner" class="bottom-slide-cookie-banner">
<div class="progress-indicator"></div>
<div class="banner-content">
<div class="banner-header">
<div class="banner-icon">🍪</div>
<div class="banner-text">
<div class="banner-title">Cookie Preferences</div>
<div class="banner-description">
We use cookies to enhance your browsing experience and provide personalized content.
<a href="#" class="cookie-link">Privacy Policy</a> |
<a href="#" class="cookie-link">Cookie Policy</a>
</div>
</div>
</div>
<div class="banner-actions">
<button class="slide-btn btn-accept" onclick="acceptCookies()">Accept All</button>
<button class="slide-btn btn-decline" onclick="declineCookies()">Decline</button>
<button class="slide-btn btn-customize" onclick="openCustomization()">Customize</button>
<button class="slide-btn btn-expand" onclick="toggleDetails()">Learn More</button>
</div>
<div id="expandableDetails" class="expandable-details">
<div class="details-grid">
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Essential Cookies</span>
<div class="slide-toggle active" data-category="essential"></div>
</div>
<div class="category-description">
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Analytics Cookies</span>
<div class="slide-toggle" data-category="analytics"></div>
</div>
<div class="category-description">
These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Marketing Cookies</span>
<div class="slide-toggle" data-category="marketing"></div>
</div>
<div class="category-description">
These cookies are used to deliver advertisements more relevant to you and your interests based on your browsing behavior.
</div>
</div>
<div class="cookie-category">
<div class="category-header">
<span class="category-title">Functional Cookies</span>
<div class="slide-toggle" data-category="functional"></div>
</div>
<div class="category-description">
These cookies enable enhanced functionality and personalization, such as remembering your preferences and settings.
</div>
</div>
</div>
</div>
</div>
</div>
<script>
class BottomSlideCookieBanner {
constructor(options = {}) {
this.options = {
autoShow: true,
showDelay: 1500,
storageKey: 'bottom_slide_cookie_consent',
expirationDays: 365,
enableAnimations: true,
slideDirection: 'bottom',
animationType: 'slide', // 'slide', 'fade', 'bounce'
progressiveDisclosure: true,
onAccept: null,
onDecline: null,
onCustomize: null,
...options
};
this.banner = document.getElementById('bottomSlideCookieBanner');
this.expandableDetails = document.getElementById('expandableDetails');
this.consent = this.getStoredConsent();
this.isVisible = false;
this.isExpanded = false;
this.init();
}
init() {
if (this.options.autoShow && !this.consent) {
setTimeout(() => this.show(), this.options.showDelay);
}
this.setupEventListeners();
this.loadConfiguration();
this.setupAnimationType();
}
setupEventListeners() {
document.querySelectorAll('.slide-toggle').forEach(toggle => {
toggle.addEventListener('click', () => {
if (toggle.dataset.category !== 'essential') {
toggle.classList.toggle('active');
this.animateToggle(toggle);
}
});
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && this.isExpanded) {
this.toggleDetails();
}
});
document.querySelectorAll('.slide-btn').forEach(btn => {
btn.addEventListener('mouseenter', () => {
this.createRipple(btn);
});
});
this.banner.addEventListener('mouseenter', () => {
if (this.isVisible) {
this.enhanceProgressIndicator();
}
});
this.banner.addEventListener('mouseleave', () => {
if (this.isVisible) {
this.resetProgressIndicator();
}
});
}
setupAnimationType() {
const animationClasses = {
slide: '',
fade: 'slide-in-fade',
bounce: 'bounce-in'
};
const animationClass = animationClasses[this.options.animationType];
if (animationClass) {
this.banner.classList.add(animationClass);
}
}
animateToggle(toggle) {
if (!this.options.enableAnimations) return;
toggle.style.transform = 'scale(0.9)';
setTimeout(() => {
toggle.style.transform = 'scale(1)';
}, 150);
toggle.style.boxShadow = '0 0 0 8px rgba(5, 150, 105, 0.2)';
setTimeout(() => {
toggle.style.boxShadow = '';
}, 300);
}
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);
}
enhanceProgressIndicator() {
if (!this.options.enableAnimations) return;
const indicator = this.banner.querySelector('.progress-indicator');
if (indicator) {
indicator.style.background = 'linear-gradient(90deg, var(--primary-color), var(--success-color))';
indicator.style.height = '4px';
}
}
resetProgressIndicator() {
if (!this.options.enableAnimations) return;
const indicator = this.banner.querySelector('.progress-indicator');
if (indicator) {
indicator.style.background = 'var(--primary-color)';
indicator.style.height = '3px';
}
}
show() {
this.banner.classList.add('show');
this.isVisible = true;
if (this.options.enableAnimations) {
this.animateEntrance();
}
}
hide() {
this.banner.classList.remove('show');
this.isVisible = false;
this.isExpanded = false;
this.expandableDetails.classList.remove('expanded');
}
animateEntrance() {
const elements = [
this.banner.querySelector('.banner-icon'),
this.banner.querySelector('.banner-title'),
this.banner.querySelector('.banner-description'),
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);
}
});
}
toggleDetails() {
this.isExpanded = !this.isExpanded;
if (this.isExpanded) {
this.expandableDetails.classList.add('expanded');
if (this.options.enableAnimations) {
this.animateDetailsExpansion();
}
} else {
this.expandableDetails.classList.remove('expanded');
}
const expandBtn = this.banner.querySelector('.btn-expand');
if (expandBtn) {
expandBtn.textContent = this.isExpanded ? 'Show Less' : 'Learn More';
}
}
animateDetailsExpansion() {
const categories = this.expandableDetails.querySelectorAll('.cookie-category');
categories.forEach((category, index) => {
category.style.opacity = '0';
category.style.transform = 'translateY(20px)';
setTimeout(() => {
category.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
category.style.opacity = '1';
category.style.transform = 'translateY(0)';
}, index * 100);
});
}
accept() {
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);
}
}
decline() {
const consent = {
essential: true,
analytics: false,
marketing: false,
functional: false,
timestamp: Date.now()
};
this.saveConsent(consent);
this.hide();
if (this.options.onDecline) {
this.options.onDecline(consent);
}
}
showSuccessAnimation() {
if (!this.options.enableAnimations) return;
const acceptBtn = this.banner.querySelector('.btn-accept');
if (acceptBtn) {
acceptBtn.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>
Accepted
`;
acceptBtn.style.background = 'var(--success-color)';
}
}
customize() {
this.toggleDetails();
if (this.options.onCustomize) {
this.options.onCustomize();
}
}
saveCustomization() {
const toggles = document.querySelectorAll('.slide-toggle');
const consent = { timestamp: Date.now() };
toggles.forEach(toggle => {
const category = toggle.dataset.category;
consent[category] = toggle.classList.contains('active');
});
this.saveConsent(consent);
this.hide();
if (this.options.onCustomize) {
this.options.onCustomize(consent);
}
}
loadConfiguration() {
if (this.consent) {
document.querySelectorAll('.slide-toggle').forEach(toggle => {
const category = toggle.dataset.category;
if (this.consent[category]) {
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;
}
setSlideDirection(direction) {
this.options.slideDirection = direction;
this.setupSlideDirection();
}
setupSlideDirection() {
const directions = {
bottom: 'translateY(100%)',
top: 'translateY(-100%)',
left: 'translateX(-100%)',
right: 'translateX(100%)'
};
const transform = directions[this.options.slideDirection] || directions.bottom;
document.documentElement.style.setProperty('--slide-distance', transform);
}
setAnimationType(type) {
this.options.animationType = type;
this.setupAnimationType();
}
enableAnimations(enabled) {
this.options.enableAnimations = enabled;
}
updateTheme(theme) {
const themes = {
light: {
'--background': '#ffffff',
'--surface': '#f9fafb',
'--text-primary': '#111827',
'--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);
});
}
}
}
const style = document.createElement('style');
style.textContent = `
@keyframes ripple {
to {
transform: translate(-50%, -50%) scale(2);
opacity: 0;
}
}
`;
document.head.appendChild(style);
const cookieBanner = new BottomSlideCookieBanner({
slideDirection: 'bottom',
animationType: 'slide',
enableAnimations: true,
progressiveDisclosure: true,
onAccept: (consent) => {
console.log('Cookies accepted:', consent);
},
onDecline: (consent) => {
console.log('Cookies declined:', consent);
},
onCustomize: (consent) => {
console.log('Custom configuration saved:', consent);
}
});
function showCookieBanner() {
cookieBanner.reset();
}
function acceptCookies() {
cookieBanner.accept();
}
function declineCookies() {
cookieBanner.decline();
}
function openCustomization() {
cookieBanner.customize();
}
function toggleDetails() {
cookieBanner.toggleDetails();
}
</script>
</body>
</html>