Html
Css
Javascript
Cookies
Rgpd
Consentement
Template
Bandeau de consentement cookies et CGU en HTML CSS JS pur : modal overlay, animations fluides, gestion des préférences et stockage localStorage sans dépendance.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="copyright" content="AngularForAll" />
<meta name="author" content="AngularForAll" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Cache-Control" content="public, max-age=604800" />
<title>Snippets Accept Condition Cookies HTML CSS JS 2026 05022045 | AngularForAll</title>
<style>
/* =============================================
RESET & VARIABLES
============================================= */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--primary-light: #e0e7ff;
--success: #10b981;
--success-light: #d1fae5;
--text: #1e293b;
--text-light: #64748b;
--bg: #ffffff;
--bg-overlay: rgba(15, 23, 42, 0.75);
--border: #e2e8f0;
--radius-sm: 8px;
--radius: 14px;
--radius-lg: 20px;
--radius-xl: 24px;
--shadow-sm: 0 1px 3px rgba(0,0,0,0.06);
--shadow: 0 4px 24px rgba(0,0,0,0.08);
--shadow-lg: 0 25px 70px rgba(0,0,0,0.15);
--transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
body {
font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
background: linear-gradient(150deg, #f8fafc 0%, #f1f5f9 30%, #e0e7ff 70%, #ede9fe 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
color: var(--text);
-webkit-font-smoothing: antialiased;
}
/* Page de démonstration */
.demo-content {
text-align: center;
max-width: 500px;
}
.demo-content h1 {
font-size: 2.5rem;
font-weight: 800;
color: #1e293b;
margin-bottom: 0.5rem;
}
.demo-content p {
color: #64748b;
font-size: 1.1rem;
margin-bottom: 1.5rem;
}
.btn-reset-consent {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: #6366f1;
color: white;
border: none;
border-radius: 25px;
font-weight: 600;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.2s;
font-family: inherit;
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
}
.btn-reset-consent:hover {
background: #4f46e5;
box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4);
transform: translateY(-1px);
}
.btn-reset-consent:active {
transform: scale(0.96);
}
/* =============================================
OVERLAY
============================================= */
.consent-overlay {
position: fixed;
inset: 0;
background: var(--bg-overlay);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
z-index: 9998;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
animation: fadeIn 0.3s ease forwards;
}
.consent-overlay.hidden {
display: none;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* =============================================
MODALE PRINCIPALE
============================================= */
.consent-modal {
background: var(--bg);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-lg);
width: 100%;
max-width: 480px;
overflow: hidden;
animation: slideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
position: relative;
z-index: 9999;
border: 1px solid rgba(0,0,0,0.06);
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(40px) scale(0.93);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
/* =============================================
EN-TÊTE
============================================= */
.consent-header {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
padding: 30px 28px 26px;
color: white;
position: relative;
overflow: hidden;
}
.consent-header::before {
content: '';
position: absolute;
top: -40%;
right: -20%;
width: 180px;
height: 180px;
background: radial-gradient(circle, rgba(255,255,255,0.12) 0%, transparent 70%);
border-radius: 50%;
}
.consent-header::after {
content: '';
position: absolute;
bottom: -35%;
left: 25%;
width: 150px;
height: 150px;
background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);
border-radius: 50%;
}
.header-icon {
width: 56px;
height: 56px;
background: rgba(255,255,255,0.18);
backdrop-filter: blur(4px);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
margin-bottom: 14px;
border: 1px solid rgba(255,255,255,0.2);
position: relative;
z-index: 1;
}
.header-title {
font-size: 1.35rem;
font-weight: 700;
letter-spacing: -0.02em;
margin-bottom: 4px;
position: relative;
z-index: 1;
}
.header-subtitle {
font-size: 0.82rem;
opacity: 0.8;
position: relative;
z-index: 1;
}
/* =============================================
CORPS
============================================= */
.consent-body {
padding: 24px 28px 8px;
}
.consent-description {
font-size: 0.9rem;
color: var(--text-light);
line-height: 1.65;
margin-bottom: 20px;
}
.consent-description a {
color: var(--primary);
font-weight: 600;
text-decoration: underline;
text-underline-offset: 3px;
transition: color 0.2s;
cursor: pointer;
}
.consent-description a:hover {
color: var(--primary-dark);
}
/* =============================================
OPTIONS
============================================= */
.consent-options {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 8px;
}
.consent-option {
display: flex;
align-items: flex-start;
gap: 14px;
padding: 16px;
background: #f8fafc;
border: 2px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
transition: all var(--transition);
position: relative;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.consent-option:hover {
border-color: #c7d2fe;
background: #f5f7ff;
box-shadow: var(--shadow-sm);
}
.consent-option.selected {
border-color: var(--primary);
background: var(--primary-light);
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.08);
}
/* Checkbox personnalisée */
.custom-checkbox {
width: 24px;
height: 24px;
border-radius: 7px;
border: 2px solid #cbd5e1;
background: white;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
transition: all var(--transition);
margin-top: 1px;
}
.consent-option.selected .custom-checkbox {
background: var(--primary);
border-color: var(--primary);
}
.custom-checkbox svg {
width: 15px;
height: 15px;
display: none;
}
.consent-option.selected .custom-checkbox svg {
display: block;
}
.option-content {
flex: 1;
min-width: 0;
}
.option-title {
font-weight: 600;
font-size: 0.92rem;
color: var(--text);
margin-bottom: 3px;
display: flex;
align-items: center;
gap: 8px;
}
.option-badge {
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 3px 9px;
border-radius: 12px;
}
.badge-required {
background: #fee2e2;
color: #dc2626;
}
.badge-optional {
background: #dbeafe;
color: #2563eb;
}
.option-description {
font-size: 0.77rem;
color: var(--text-light);
line-height: 1.45;
}
/* =============================================
PIED
============================================= */
.consent-footer {
padding: 16px 28px 24px;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.btn {
padding: 12px 22px;
border-radius: 25px;
font-weight: 600;
font-size: 0.85rem;
font-family: inherit;
cursor: pointer;
transition: all var(--transition);
border: 2px solid transparent;
outline: none;
white-space: nowrap;
flex: 1;
min-width: 110px;
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.btn:active {
transform: scale(0.95);
}
.btn-primary {
background: var(--primary);
color: white;
border-color: var(--primary);
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
}
.btn-primary:hover {
background: var(--primary-dark);
border-color: var(--primary-dark);
box-shadow: 0 6px 22px rgba(99, 102, 241, 0.4);
transform: translateY(-1px);
}
.btn-outline {
background: white;
color: var(--text-light);
border-color: var(--border);
}
.btn-outline:hover {
background: #f8fafc;
border-color: #cbd5e1;
color: var(--text);
}
.btn-ghost {
background: transparent;
color: var(--text-light);
border-color: transparent;
flex: 0;
min-width: auto;
padding: 12px 16px;
}
.btn-ghost:hover {
background: #f1f5f9;
color: var(--text);
}
/* =============================================
TOAST
============================================= */
.toast {
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%) translateY(120px);
background: #1e293b;
color: white;
padding: 14px 26px;
border-radius: 30px;
font-weight: 600;
font-size: 0.88rem;
z-index: 10000;
box-shadow: 0 12px 35px rgba(0,0,0,0.25);
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
display: flex;
align-items: center;
gap: 8px;
white-space: nowrap;
}
.toast.show {
transform: translateX(-50%) translateY(0);
}
/* =============================================
RESPONSIVE
============================================= */
@media (max-width: 500px) {
.consent-header {
padding: 24px 20px 20px;
}
.consent-body {
padding: 18px 20px 4px;
}
.consent-footer {
padding: 12px 20px 18px;
flex-direction: column;
}
.btn {
width: 100%;
flex: none;
}
.btn-ghost {
order: -1;
align-self: flex-end;
width: auto;
margin-bottom: 4px;
}
.header-title {
font-size: 1.2rem;
}
.consent-option {
padding: 14px;
}
}
</style>
</head>
<body>
<!-- =============================================
CONTENU DE DÉMONSTRATION
============================================= -->
<div class="demo-content">
<h1>🍪 Cookies</h1>
<p>Ce site utilise des cookies pour améliorer votre expérience.</p>
<button class="btn-reset-consent" id="btnResetConsent">
🔄 Réinitialiser le consentement
</button>
</div>
<!-- =============================================
OVERLAY + MODALE
============================================= -->
<div class="consent-overlay" id="consentOverlay">
<div class="consent-modal" role="dialog" aria-labelledby="consentTitle" aria-modal="true">
<!-- En-tête -->
<div class="consent-header">
<div class="header-icon">🍪</div>
<h2 class="header-title" id="consentTitle">Respectons votre vie privée</h2>
<p class="header-subtitle">Nous utilisons des cookies pour améliorer votre expérience</p>
</div>
<!-- Corps -->
<div class="consent-body">
<p class="consent-description">
En poursuivant votre navigation, vous acceptez notre
<a href="#" onclick="event.preventDefault(); alert('Politique de confidentialité - Document à venir')">Politique de confidentialité</a> et nos
<a href="#" onclick="event.preventDefault(); alert('CGU - Document à venir')">Conditions Générales d'Utilisation</a>.
Vous pouvez personnaliser vos préférences ci-dessous.
</p>
<!-- Options -->
<div class="consent-options">
<!-- Cookies Essentiels -->
<div class="consent-option selected" id="optionEssential" data-essential="true">
<div class="custom-checkbox">
<svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="option-content">
<div class="option-title">
Cookies Essentiels
<span class="option-badge badge-required">Requis</span>
</div>
<div class="option-description">Nécessaires au bon fonctionnement du site. Toujours activés.</div>
</div>
</div>
<!-- Cookies Analytics -->
<div class="consent-option" id="optionAnalytics">
<div class="custom-checkbox">
<svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="option-content">
<div class="option-title">
Cookies Analytiques
<span class="option-badge badge-optional">Optionnel</span>
</div>
<div class="option-description">Nous aident à comprendre comment vous utilisez le site.</div>
</div>
</div>
<!-- Cookies Marketing -->
<div class="consent-option" id="optionMarketing">
<div class="custom-checkbox">
<svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="option-content">
<div class="option-title">
Cookies Marketing
<span class="option-badge badge-optional">Optionnel</span>
</div>
<div class="option-description">Utilisés pour des publicités personnalisées.</div>
</div>
</div>
</div>
</div>
<!-- Pied -->
<div class="consent-footer">
<button class="btn btn-ghost" id="btnCustomize">
⚙️ Personnaliser
</button>
<button class="btn btn-outline" id="btnRefuse">
✕ Refuser tout
</button>
<button class="btn btn-primary" id="btnAccept">
✓ Accepter tout
</button>
</div>
</div>
</div>
<!-- =============================================
TOAST
============================================= -->
<div class="toast" id="toast">
<span id="toastIcon">✅</span>
<span id="toastMessage">Préférences enregistrées</span>
</div>
<script>
(function() {
// ============ ÉTAT ============
const consentState = {
essential: true, // Toujours activé
analytics: false,
marketing: false,
};
// Clé pour le localStorage
const STORAGE_KEY = 'cookieConsent_v2';
// ============ ÉLÉMENTS DOM ============
const overlay = document.getElementById('consentOverlay');
const optionEssential = document.getElementById('optionEssential');
const optionAnalytics = document.getElementById('optionAnalytics');
const optionMarketing = document.getElementById('optionMarketing');
const btnAccept = document.getElementById('btnAccept');
const btnRefuse = document.getElementById('btnRefuse');
const btnCustomize = document.getElementById('btnCustomize');
const btnResetConsent = document.getElementById('btnResetConsent');
const toast = document.getElementById('toast');
const toastIcon = document.getElementById('toastIcon');
const toastMessage = document.getElementById('toastMessage');
// ============ FONCTIONS ============
function updateUI() {
// Essentiel toujours sélectionné
optionEssential.classList.add('selected');
// Analytics
if (consentState.analytics) {
optionAnalytics.classList.add('selected');
} else {
optionAnalytics.classList.remove('selected');
}
// Marketing
if (consentState.marketing) {
optionMarketing.classList.add('selected');
} else {
optionMarketing.classList.remove('selected');
}
}
function toggleOption(type) {
if (type === 'essential') {
showToast('ℹ️', 'Les cookies essentiels sont obligatoires');
return;
}
if (type === 'analytics') {
consentState.analytics = !consentState.analytics;
}
if (type === 'marketing') {
consentState.marketing = !consentState.marketing;
}
updateUI();
}
function acceptAll() {
consentState.analytics = true;
consentState.marketing = true;
updateUI();
saveAndClose('✅', 'Tous les cookies ont été acceptés !');
}
function refuseAll() {
consentState.analytics = false;
consentState.marketing = false;
updateUI();
saveAndClose('🔒', 'Seuls les cookies essentiels sont activés');
}
function saveCustom() {
saveAndClose('💾', 'Vos préférences ont été enregistrées');
}
function saveAndClose(icon, message) {
// Sauvegarder dans localStorage avec gestion d'erreur
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({
essential: consentState.essential,
analytics: consentState.analytics,
marketing: consentState.marketing,
timestamp: Date.now(),
}));
console.log('🍪 Consentement enregistré :', consentState);
} catch (e) {
console.warn('⚠️ Impossible de sauvegarder les préférences :', e.message);
}
// Afficher le toast
showToast(icon, message);
// Fermer la modale avec animation
overlay.style.opacity = '0';
overlay.style.transition = 'opacity 0.35s ease';
setTimeout(() => {
overlay.classList.add('hidden');
overlay.style.opacity = '1';
}, 350);
}
function resetConsent() {
// Supprimer du localStorage
try {
localStorage.removeItem(STORAGE_KEY);
} catch (e) {
console.warn('⚠️ Impossible de supprimer les préférences :', e.message);
}
// Réinitialiser l'état
consentState.analytics = false;
consentState.marketing = false;
// Réafficher la modale
overlay.classList.remove('hidden');
overlay.style.opacity = '1';
// Réanimer la modale
const modal = overlay.querySelector('.consent-modal');
modal.style.animation = 'none';
modal.offsetHeight;
modal.style.animation = 'slideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards';
updateUI();
showToast('🔄', 'Consentement réinitialisé');
console.log('🍪 Consentement réinitialisé');
}
// ============ TOAST ============
let toastTimer;
function showToast(icon, message) {
toastIcon.textContent = icon;
toastMessage.textContent = message;
toast.classList.add('show');
clearTimeout(toastTimer);
toastTimer = setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
// ============ ÉVÉNEMENTS ============
// Clic sur les options
optionAnalytics.addEventListener('click', (e) => {
e.stopPropagation();
toggleOption('analytics');
});
optionMarketing.addEventListener('click', (e) => {
e.stopPropagation();
toggleOption('marketing');
});
optionEssential.addEventListener('click', (e) => {
e.stopPropagation();
toggleOption('essential');
});
// Boutons
btnAccept.addEventListener('click', (e) => {
e.stopPropagation();
acceptAll();
});
btnRefuse.addEventListener('click', (e) => {
e.stopPropagation();
refuseAll();
});
btnCustomize.addEventListener('click', (e) => {
e.stopPropagation();
saveCustom();
});
// Bouton de réinitialisation
btnResetConsent.addEventListener('click', (e) => {
e.stopPropagation();
resetConsent();
});
// Raccourcis clavier
document.addEventListener('keydown', (e) => {
// Seulement si l'overlay est visible
if (!overlay.classList.contains('hidden')) {
if (e.key === 'Escape') {
saveCustom();
}
if (e.key === 'a' && e.ctrlKey) {
e.preventDefault();
acceptAll();
}
if (e.key === 'r' && e.ctrlKey) {
e.preventDefault();
refuseAll();
}
}
});
// Empêcher la fermeture en cliquant à l'extérieur
overlay.addEventListener('click', (e) => {
if (e.target === overlay) {
// Optionnel : sauvegarder l'état actuel
// saveCustom();
}
});
// ============ VÉRIFICATION AU CHARGEMENT ============
function checkExistingConsent() {
try {
const saved = localStorage.getItem(STORAGE_KEY);
if (saved) {
const parsed = JSON.parse(saved);
// Vérifier si le consentement a plus de 6 mois (optionnel)
const sixMonths = 180 * 24 * 60 * 60 * 1000;
const isExpired = Date.now() - parsed.timestamp > sixMonths;
if (!isExpired) {
// Consentement valide : cacher la modale
overlay.classList.add('hidden');
// Restaurer l'état (pour affichage)
consentState.analytics = parsed.analytics || false;
consentState.marketing = parsed.marketing || false;
console.log('🍪 Consentement existant valide trouvé');
return true;
} else {
// Consentement expiré : supprimer et afficher
localStorage.removeItem(STORAGE_KEY);
console.log('🍪 Consentement expiré, nouvelle demande');
}
}
} catch (e) {
// Erreur de parsing ou localStorage non disponible
console.warn('🍪 Erreur lors de la vérification du consentement :', e.message);
}
// Afficher la modale
overlay.classList.remove('hidden');
return false;
}
// ============ INITIALISATION ============
function init() {
// Vérifier le consentement existant
const hasConsent = checkExistingConsent();
// Mettre à jour l'UI
updateUI();
if (!hasConsent) {
console.log('🍪 Veuillez définir vos préférences de cookies');
}
console.log('✅ Module de consentement initialisé');
}
// Démarrer
init();
})();
</script>
</body>
</html>
Télécharger le fichier source