Bandeau Cookies & CGU HTML CSS JS

Extraits & Composants HTML 07/04/2026 20:00:00 angularforall.com
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

Partager