interactive
intermediate
cookie-banner
gdpr
privacy
consent
responsive
modern
animated
Categoría · Interactivo Nivel de Dificultad · Intermedio Publicado el · 15 de enero de 2024

Banner de Consentimiento de Cookies con Tarjeta Flotante

Un elegante banner de consentimiento de cookies estilo tarjeta flotante con animaciones suaves, efectos hover y patrones de diseño de tarjetas modernas

#cookie-banner #gdpr #privacy #consent #responsive #modern #animated

Diseño Responsivo

Soporte para Modo Oscuro

No

líneas

1125

Compatibilidad del Navegador

No

Vista Previa en Vivo

Interactúa con el componente sin salir de la página.

400px

Un banner de consentimiento de cookies bellamente diseñado estilo tarjeta flotante que aparece con animaciones suaves y elegantes efectos hover. Presenta un diseño de tarjeta moderno con sombras sutiles, esquinas redondeadas y elementos interactivos que mejoran la participación del usuario.

Características

  • Diseño de Tarjeta Flotante: Diseño elegante estilo tarjeta con sombras sutiles y esquinas redondeadas
  • Animaciones Suaves: Animaciones de entrada fluidas y micro-interacciones
  • Efectos Hover: Estados hover interactivos con transiciones de escala y sombra
  • Tipografía Moderna: Fuentes limpias y legibles con jerarquía adecuada
  • Cumple RGPD: Gestión completa de consentimiento con controles granulares
  • Accesibilidad Primero: Navegación completa por teclado y soporte para lectores de pantalla
  • Diseño Responsivo: Se adapta hermosamente a todos los tamaños y orientaciones de pantalla
  • Estilo Personalizable: Fácil personalización de temas con variables CSS
  • Optimizado para Rendimiento: Implementación ligera y de carga rápida

Vista Previa

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Banner de Cookies Tarjeta Flotante</title>
    <style>
        :root {
            --color-primario: #3b82f6;
            --color-primario-hover: #2563eb;
            --color-secundario: #6b7280;
            --color-exito: #10b981;
            --color-exito-hover: #059669;
            --color-peligro: #ef4444;
            --color-peligro-hover: #dc2626;
            --fondo: #ffffff;
            --superficie: #f8fafc;
            --texto-primario: #1f2937;
            --texto-secundario: #6b7280;
            --texto-silenciado: #9ca3af;
            --color-borde: #e5e7eb;
            --sombra-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
            --sombra-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            --sombra-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            --sombra-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
            --radio-borde: 12px;
            --radio-borde-lg: 16px;
            --transicion: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            --transicion-rapida: 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(--texto-primario);
            line-height: 1.6;
            padding: 2rem;
        }

        .contenedor-demo {
            max-width: 1200px;
            margin: 0 auto;
            text-align: center;
            color: white;
        }

        .contenedor-demo 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;
        }

        .contenedor-demo p {
            font-size: 1.2rem;
            opacity: 0.9;
            margin-bottom: 2rem;
        }

        .btn-demo {
            padding: 1rem 2rem;
            border: none;
            border-radius: var(--radio-borde);
            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(--transicion);
            border: 1px solid rgba(255, 255, 255, 0.3);
        }

        .btn-demo:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }.banner-cookies-flotante {
            position: fixed;
            bottom: 2rem;
            right: 2rem;
            width: 420px;
            max-width: calc(100vw - 4rem);
            background: var(--fondo);
            border-radius: var(--radio-borde-lg);
            box-shadow: var(--sombra-xl);
            border: 1px solid var(--color-borde);
            overflow: hidden;
            transform: translateY(120%) scale(0.8);
            opacity: 0;
            transition: var(--transicion);
            z-index: 10000;
            backdrop-filter: blur(20px);
        }

        .banner-cookies-flotante.mostrar {
            transform: translateY(0) scale(1);
            opacity: 1;
        }

        .banner-cookies-flotante:hover {
            transform: translateY(-4px) scale(1.02);
            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
        }

        .encabezado-banner {
            background: linear-gradient(135deg, var(--color-primario) 0%, var(--color-primario-hover) 100%);
            padding: 1.5rem;
            color: white;
            position: relative;
            overflow: hidden;
        }

        .encabezado-banner::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
            animation: brillo 3s infinite;
        }

        @keyframes brillo {
            0% { left: -100%; }
            100% { left: 100%; }
        }

        .icono-banner {
            width: 48px;
            height: 48px;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            margin-bottom: 1rem;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.3);
            animation: flotar 3s ease-in-out infinite;
        }

        @keyframes flotar {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-5px); }
        }

        .titulo-banner {
            font-size: 1.25rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
            position: relative;
            z-index: 1;
        }

        .subtitulo-banner {
            font-size: 0.9rem;
            opacity: 0.9;
            position: relative;
            z-index: 1;
        }

        .contenido-banner {
            padding: 1.5rem;
        }

        .descripcion-cookies {
            color: var(--texto-secundario);
            font-size: 0.95rem;
            line-height: 1.6;
            margin-bottom: 1.5rem;
        }

        .enlace-cookies {
            color: var(--color-primario);
            text-decoration: none;
            font-weight: 600;
            transition: var(--transicion-rapida);
            position: relative;
        }

        .enlace-cookies::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 0;
            height: 2px;
            background: var(--color-primario);
            transition: width 0.3s ease;
        }

        .enlace-cookies:hover {
            color: var(--color-primario-hover);
        }

        .enlace-cookies:hover::after {
            width: 100%;
        }

        .acciones-cookies {
            display: flex;
            gap: 0.75rem;
            margin-top: 1.5rem;
        }.btn-tarjeta {
            flex: 1;
            padding: 0.75rem 1rem;
            border: none;
            border-radius: var(--radio-borde);
            font-family: inherit;
            font-size: 0.9rem;
            font-weight: 600;
            cursor: pointer;
            transition: var(--transicion);
            position: relative;
            overflow: hidden;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .btn-tarjeta::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 0;
            height: 0;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
            transform: translate(-50%, -50%);
            transition: width 0.6s ease, height 0.6s ease;
        }

        .btn-tarjeta:hover::before {
            width: 300px;
            height: 300px;
        }

        .btn-aceptar {
            background: var(--color-exito);
            color: white;
            box-shadow: var(--sombra-md);
        }

        .btn-aceptar:hover {
            background: var(--color-exito-hover);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }

        .btn-rechazar {
            background: var(--color-peligro);
            color: white;
            box-shadow: var(--sombra-md);
        }

        .btn-rechazar:hover {
            background: var(--color-peligro-hover);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }

        .btn-configuracion {
            background: var(--superficie);
            color: var(--texto-primario);
            border: 1px solid var(--color-borde);
            box-shadow: var(--sombra-sm);
        }

        .btn-configuracion:hover {
            background: var(--color-borde);
            transform: translateY(-2px);
            box-shadow: var(--sombra-md);
        }

        .btn-tarjeta:active {
            transform: translateY(0);
        }.modal-configuracion-cookies {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(8px);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10001;
            opacity: 0;
            visibility: hidden;
            transition: var(--transicion);
        }

        .modal-configuracion-cookies.mostrar {
            opacity: 1;
            visibility: visible;
        }

        .tarjeta-configuracion {
            background: var(--fondo);
            border-radius: var(--radio-borde-lg);
            box-shadow: var(--sombra-xl);
            border: 1px solid var(--color-borde);
            width: 90%;
            max-width: 600px;
            max-height: 80vh;
            overflow: hidden;
            transform: scale(0.9) translateY(20px);
            transition: var(--transicion);
        }

        .modal-configuracion-cookies.mostrar .tarjeta-configuracion {
            transform: scale(1) translateY(0);
        }

        .encabezado-configuracion {
            background: linear-gradient(135deg, var(--color-primario) 0%, var(--color-primario-hover) 100%);
            padding: 2rem;
            color: white;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .titulo-configuracion {
            font-size: 1.5rem;
            font-weight: 700;
        }

        .btn-cerrar {
            width: 40px;
            height: 40px;
            border: none;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            font-size: 1.25rem;
            cursor: pointer;
            transition: var(--transicion-rapida);
            display: flex;
            align-items: center;
            justify-content: center;
            backdrop-filter: blur(10px);
        }

        .btn-cerrar:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: scale(1.1) rotate(90deg);
        }

        .cuerpo-configuracion {
            padding: 2rem;
            max-height: 60vh;
            overflow-y: auto;
        }

        .categoria-cookies {
            margin-bottom: 2rem;
            padding: 1.5rem;
            background: var(--superficie);
            border: 1px solid var(--color-borde);
            border-radius: var(--radio-borde);
            transition: var(--transicion-rapida);
        }

        .categoria-cookies:hover {
            box-shadow: var(--sombra-md);
            transform: translateY(-1px);
        }

        .encabezado-categoria {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1rem;
        }

        .titulo-categoria {
            font-weight: 700;
            font-size: 1.1rem;
            color: var(--texto-primario);
        }

        .descripcion-categoria {
            font-size: 0.9rem;
            color: var(--texto-secundario);
            line-height: 1.6;
        }.interruptor-tarjeta {
            position: relative;
            width: 56px;
            height: 28px;
            background: var(--color-borde);
            border-radius: 14px;
            cursor: pointer;
            transition: var(--transicion);
            border: 2px solid transparent;
        }

        .interruptor-tarjeta.activo {
            background: var(--color-exito);
            box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
        }

        .interruptor-tarjeta::before {
            content: '';
            position: absolute;
            top: 2px;
            left: 2px;
            width: 20px;
            height: 20px;
            background: white;
            border-radius: 50%;
            transition: var(--transicion);
            box-shadow: var(--sombra-sm);
        }

        .interruptor-tarjeta.activo::before {
            transform: translateX(28px);
            box-shadow: var(--sombra-md);
        }

        .interruptor-tarjeta:hover {
            transform: scale(1.05);
        }

        .acciones-configuracion {
            display: flex;
            gap: 1rem;
            justify-content: flex-end;
            padding: 1.5rem 2rem;
            background: var(--superficie);
            border-top: 1px solid var(--color-borde);
        }@media (max-width: 768px) {
            .banner-cookies-flotante {
                bottom: 1rem;
                right: 1rem;
                left: 1rem;
                width: auto;
                max-width: none;
            }

            .banner-cookies-flotante:hover {
                transform: translateY(-2px) scale(1.01);
            }

            .acciones-cookies {
                flex-direction: column;
            }

            .btn-tarjeta {
                flex: none;
            }

            .tarjeta-configuracion {
                margin: 1rem;
                width: calc(100% - 2rem);
            }

            .encabezado-configuracion {
                padding: 1.5rem;
            }

            .cuerpo-configuracion {
                padding: 1.5rem;
            }

            .acciones-configuracion {
                padding: 1rem 1.5rem;
                flex-direction: column;
            }
        }

        @media (max-width: 480px) {
            body {
                padding: 1rem;
            }

            .contenedor-demo h1 {
                font-size: 2rem;
            }

            .banner-cookies-flotante {
                bottom: 0.5rem;
                right: 0.5rem;
                left: 0.5rem;
            }

            .encabezado-banner {
                padding: 1rem;
            }

            .contenido-banner {
                padding: 1rem;
            }
        }.puntos-carga {
            display: inline-flex;
            gap: 4px;
        }

        .puntos-carga span {
            width: 6px;
            height: 6px;
            background: currentColor;
            border-radius: 50%;
            animation: carga 1.4s infinite ease-in-out;
        }

        .puntos-carga span:nth-child(1) { animation-delay: -0.32s; }
        .puntos-carga span:nth-child(2) { animation-delay: -0.16s; }

        @keyframes carga {
            0%, 80%, 100% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            40% {
                transform: scale(1);
                opacity: 1;
            }
        }.marca-exito {
            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: llenar 0.4s ease-in-out 0.4s forwards, escalar 0.3s ease-in-out 0.9s both;
        }

        .circulo-marca-exito {
            stroke-dasharray: 166;
            stroke-dashoffset: 166;
            stroke-width: 2;
            stroke-miterlimit: 10;
            stroke: currentColor;
            fill: none;
            animation: trazo 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
        }

        .check-marca-exito {
            transform-origin: 50% 50%;
            stroke-dasharray: 48;
            stroke-dashoffset: 48;
            animation: trazo 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
        }

        @keyframes trazo {
            100% {
                stroke-dashoffset: 0;
            }
        }

        @keyframes escalar {
            0%, 100% {
                transform: none;
            }
            50% {
                transform: scale3d(1.1, 1.1, 1);
            }
        }

        @keyframes llenar {
            100% {
                box-shadow: inset 0px 0px 0px 30px currentColor;
            }
        }
    </style>
</head>
<body>
    <div class="contenedor-demo">
        <h1>Diseño de Tarjeta Flotante</h1>
        <p>Experimenta la elegancia del diseño de tarjeta flotante con animaciones suaves e interacciones modernas</p>
        <button class="btn-demo" onclick="mostrarBannerCookies()">Mostrar Banner de Cookies</button>
    </div>

    
    <div id="bannerCookiesFlotante" class="banner-cookies-flotante">
        <div class="encabezado-banner">
            <div class="icono-banner">🍪</div>
            <div class="titulo-banner">Preferencias de Cookies</div>
            <div class="subtitulo-banner">Valoramos tu privacidad</div>
        </div>
        <div class="contenido-banner">
            <div class="descripcion-cookies">
                Utilizamos cookies para mejorar tu experiencia de navegación y proporcionar contenido personalizado. 
                <a href="#" class="enlace-cookies">Política de Privacidad</a> | 
                <a href="#" class="enlace-cookies">Política de Cookies</a>
            </div>
            <div class="acciones-cookies">
                <button class="btn-tarjeta btn-aceptar" onclick="aceptarCookies()">Aceptar Todo</button>
                <button class="btn-tarjeta btn-rechazar" onclick="rechazarCookies()">Rechazar</button>
                <button class="btn-tarjeta btn-configuracion" onclick="abrirConfiguracion()">Personalizar</button>
            </div>
        </div>
    </div>

    
    <div id="modalConfiguracionCookies" class="modal-configuracion-cookies">
        <div class="tarjeta-configuracion">
            <div class="encabezado-configuracion">
                <h3 class="titulo-configuracion">Configuración de Cookies</h3>
                <button class="btn-cerrar" onclick="cerrarConfiguracion()">&times;</button>
            </div>
            <div class="cuerpo-configuracion">
                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies Esenciales</span>
                        <div class="interruptor-tarjeta activo" data-categoria="esenciales"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies son necesarias para que el sitio web funcione y no se pueden desactivar. Generalmente solo se establecen en respuesta a acciones realizadas por ti.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies de Análisis</span>
                        <div class="interruptor-tarjeta" data-categoria="analiticas"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies nos ayudan a entender cómo los visitantes interactúan con nuestro sitio web recopilando y reportando información de forma anónima.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies de Marketing</span>
                        <div class="interruptor-tarjeta" data-categoria="marketing"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies se utilizan para entregar anuncios más relevantes para ti y tus intereses basados en tu comportamiento de navegación.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies Funcionales</span>
                        <div class="interruptor-tarjeta" data-categoria="funcionales"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies habilitan funcionalidad mejorada y personalización, como recordar tus preferencias y configuraciones.
                    </div>
                </div>
            </div>
            <div class="acciones-configuracion">
                <button class="btn-tarjeta btn-rechazar" onclick="guardarConfiguracion(false)">Guardar Preferencias</button>
                <button class="btn-tarjeta btn-aceptar" onclick="guardarConfiguracion(true)">Aceptar Todo</button>
            </div>
        </div>
    </div>

    <script>
        class BannerCookiesTarjetaFlotante {
            constructor(opciones = {}) {
                this.opciones = {
                    mostrarAuto: true,
                    retrasoMostrar: 1500,
                    claveAlmacenamiento: 'consentimiento_cookies_tarjeta_flotante',
                    diasExpiracion: 365,
                    habilitarAnimaciones: true,
                    posicion: 'abajo-derecha',
                    alAceptar: null,
                    alRechazar: null,
                    alGuardarConfiguracion: null,
                    ...opciones
                };

                this.banner = document.getElementById('bannerCookiesFlotante');
                this.modal = document.getElementById('modalConfiguracionCookies');
                this.consentimiento = this.obtenerConsentimientoAlmacenado();
                this.esVisible = false;

                this.inicializar();
            }

            inicializar() {
                if (this.opciones.mostrarAuto && !this.consentimiento) {
                    setTimeout(() => this.mostrar(), this.opciones.retrasoMostrar);
                }

                this.configurarEventListeners();
                this.cargarConfiguracion();
                this.configurarPosicion();
            }

            configurarEventListeners() {

                document.querySelectorAll('.interruptor-tarjeta').forEach(interruptor => {
                    interruptor.addEventListener('click', () => {
                        if (interruptor.dataset.categoria !== 'esenciales') {
                            interruptor.classList.toggle('activo');
                            this.animarInterruptor(interruptor);
                        }
                    });
                });

                this.modal.addEventListener('click', (e) => {
                    if (e.target === this.modal) {
                        this.cerrarConfiguracion();
                    }
                });

                document.addEventListener('keydown', (e) => {
                    if (e.key === 'Escape') {
                        this.cerrarConfiguracion();
                    }
                });

                document.querySelectorAll('.btn-tarjeta').forEach(btn => {
                    btn.addEventListener('mouseenter', () => {
                        this.crearOnda(btn);
                    });
                });

                this.banner.addEventListener('mouseenter', () => {
                    if (this.esVisible) {
                        this.mejorarEfectoHover();
                    }
                });

                this.banner.addEventListener('mouseleave', () => {
                    if (this.esVisible) {
                        this.resetearEfectoHover();
                    }
                });
            }

            configurarPosicion() {
                const posiciones = {
                    'abajo-derecha': { bottom: '2rem', right: '2rem', left: 'auto', top: 'auto' },
                    'abajo-izquierda': { bottom: '2rem', left: '2rem', right: 'auto', top: 'auto' },
                    'arriba-derecha': { top: '2rem', right: '2rem', left: 'auto', bottom: 'auto' },
                    'arriba-izquierda': { top: '2rem', left: '2rem', right: 'auto', bottom: 'auto' }
                };

                const pos = posiciones[this.opciones.posicion] || posiciones['abajo-derecha'];
                Object.assign(this.banner.style, pos);
            }

            animarInterruptor(interruptor) {
                if (!this.opciones.habilitarAnimaciones) return;

                interruptor.style.transform = 'scale(0.9)';
                setTimeout(() => {
                    interruptor.style.transform = 'scale(1)';
                }, 150);

                interruptor.style.boxShadow = '0 0 0 8px rgba(16, 185, 129, 0.2)';
                setTimeout(() => {
                    interruptor.style.boxShadow = '';
                }, 300);
            }

            crearOnda(boton) {
                if (!this.opciones.habilitarAnimaciones) return;

                const onda = document.createElement('span');
                const rect = boton.getBoundingClientRect();
                const tamaño = Math.max(rect.width, rect.height);
                
                onda.style.width = onda.style.height = tamaño + 'px';
                onda.style.left = '50%';
                onda.style.top = '50%';
                onda.style.transform = 'translate(-50%, -50%) scale(0)';
                onda.style.position = 'absolute';
                onda.style.borderRadius = '50%';
                onda.style.background = 'rgba(255, 255, 255, 0.3)';
                onda.style.pointerEvents = 'none';
                onda.style.animation = 'onda 0.6s ease-out';
                
                boton.style.position = 'relative';
                boton.style.overflow = 'hidden';
                boton.appendChild(onda);
                
                setTimeout(() => {
                    onda.remove();
                }, 600);
            }

            mejorarEfectoHover() {
                if (!this.opciones.habilitarAnimaciones) return;
                
                const icono = this.banner.querySelector('.icono-banner');
                if (icono) {
                    icono.style.transform = 'scale(1.1) rotate(5deg)';
                }
            }

            resetearEfectoHover() {
                if (!this.opciones.habilitarAnimaciones) return;
                
                const icono = this.banner.querySelector('.icono-banner');
                if (icono) {
                    icono.style.transform = '';
                }
            }

            mostrar() {
                this.banner.classList.add('mostrar');
                this.esVisible = true;
                
                if (this.opciones.habilitarAnimaciones) {
                    this.animarEntrada();
                }
            }

            ocultar() {
                this.banner.classList.remove('mostrar');
                this.esVisible = false;
            }

            animarEntrada() {
                const elementos = [
                    this.banner.querySelector('.icono-banner'),
                    this.banner.querySelector('.titulo-banner'),
                    this.banner.querySelector('.subtitulo-banner'),
                    this.banner.querySelector('.descripcion-cookies'),
                    this.banner.querySelector('.acciones-cookies')
                ];

                elementos.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);
                    }
                });
            }

            aceptar() {
                const consentimiento = {
                    esenciales: true,
                    analiticas: true,
                    marketing: true,
                    funcionales: true,
                    marcaTiempo: Date.now()
                };

                this.guardarConsentimiento(consentimiento);
                this.mostrarAnimacionExito();
                
                setTimeout(() => {
                    this.ocultar();
                }, 1500);

                if (this.opciones.alAceptar) {
                    this.opciones.alAceptar(consentimiento);
                }
            }

            rechazar() {
                const consentimiento = {
                    esenciales: true,
                    analiticas: false,
                    marketing: false,
                    funcionales: false,
                    marcaTiempo: Date.now()
                };

                this.guardarConsentimiento(consentimiento);
                this.ocultar();

                if (this.opciones.alRechazar) {
                    this.opciones.alRechazar(consentimiento);
                }
            }

            mostrarAnimacionExito() {
                if (!this.opciones.habilitarAnimaciones) return;

                const btnAceptar = this.banner.querySelector('.btn-aceptar');
                if (btnAceptar) {
                    btnAceptar.innerHTML = `
                        <svg class="marca-exito" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
                            <circle class="circulo-marca-exito" cx="26" cy="26" r="25" fill="none"/>
                            <path class="check-marca-exito" fill="none" d="m14.1 27.2l7.1 7.2 16.7-16.8"/>
                        </svg>
                        Aceptado
                    `;
                    btnAceptar.style.background = 'var(--color-exito)';
                }
            }

            abrirConfiguracion() {
                this.modal.classList.add('mostrar');
                document.body.style.overflow = 'hidden';
                
                if (this.opciones.habilitarAnimaciones) {
                    this.animarEntradaModal();
                }
            }

            cerrarConfiguracion() {
                this.modal.classList.remove('mostrar');
                document.body.style.overflow = '';
            }

            animarEntradaModal() {
                const categorias = this.modal.querySelectorAll('.categoria-cookies');
                categorias.forEach((categoria, index) => {
                    categoria.style.opacity = '0';
                    categoria.style.transform = 'translateX(-20px)';
                    
                    setTimeout(() => {
                        categoria.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
                        categoria.style.opacity = '1';
                        categoria.style.transform = 'translateX(0)';
                    }, index * 100);
                });
            }

            guardarConfiguracion(aceptarTodo = false) {
                const interruptores = document.querySelectorAll('.interruptor-tarjeta');
                const consentimiento = { marcaTiempo: Date.now() };

                interruptores.forEach(interruptor => {
                    const categoria = interruptor.dataset.categoria;
                    if (aceptarTodo) {
                        consentimiento[categoria] = true;
                        interruptor.classList.add('activo');
                    } else {
                        consentimiento[categoria] = interruptor.classList.contains('activo');
                    }
                });

                this.guardarConsentimiento(consentimiento);
                this.cerrarConfiguracion();
                this.ocultar();

                if (this.opciones.alGuardarConfiguracion) {
                    this.opciones.alGuardarConfiguracion(consentimiento);
                }
            }

            cargarConfiguracion() {
                if (this.consentimiento) {
                    document.querySelectorAll('.interruptor-tarjeta').forEach(interruptor => {
                        const categoria = interruptor.dataset.categoria;
                        if (this.consentimiento[categoria]) {
                            interruptor.classList.add('activo');
                        } else {
                            interruptor.classList.remove('activo');
                        }
                    });
                }
            }

            guardarConsentimiento(consentimiento) {
                const fechaExpiracion = new Date();
                fechaExpiracion.setDate(fechaExpiracion.getDate() + this.opciones.diasExpiracion);
                
                const datosConsentimiento = {
                    ...consentimiento,
                    expiracion: fechaExpiracion.getTime()
                };

                localStorage.setItem(this.opciones.claveAlmacenamiento, JSON.stringify(datosConsentimiento));
                this.consentimiento = consentimiento;
            }

            obtenerConsentimientoAlmacenado() {
                try {
                    const almacenado = localStorage.getItem(this.opciones.claveAlmacenamiento);
                    if (almacenado) {
                        const datos = JSON.parse(almacenado);
                        if (datos.expiracion && Date.now() < datos.expiracion) {
                            return datos;
                        } else {
                            localStorage.removeItem(this.opciones.claveAlmacenamiento);
                        }
                    }
                } catch (e) {
                    console.error('Error al leer el consentimiento de cookies:', e);
                }
                return null;
            }

            resetear() {
                localStorage.removeItem(this.opciones.claveAlmacenamiento);
                this.consentimiento = null;
                this.mostrar();
            }

            obtenerConsentimiento() {
                return this.consentimiento;
            }

            establecerPosicion(posicion) {
                this.opciones.posicion = posicion;
                this.configurarPosicion();
            }

            habilitarAnimaciones(habilitado) {
                this.opciones.habilitarAnimaciones = habilitado;
            }

            actualizarTema(tema) {
                const temas = {
                    claro: {
                        '--fondo': '#ffffff',
                        '--superficie': '#f8fafc',
                        '--texto-primario': '#1f2937',
                        '--texto-secundario': '#6b7280'
                    },
                    oscuro: {
                        '--fondo': '#1f2937',
                        '--superficie': '#374151',
                        '--texto-primario': '#f9fafb',
                        '--texto-secundario': '#d1d5db'
                    }
                };

                if (temas[tema]) {
                    Object.entries(temas[tema]).forEach(([propiedad, valor]) => {
                        document.documentElement.style.setProperty(propiedad, valor);
                    });
                }
            }
        }

        const estilo = document.createElement('style');
        estilo.textContent = `
            @keyframes onda {
                to {
                    transform: translate(-50%, -50%) scale(2);
                    opacity: 0;
                }
            }
        `;
        document.head.appendChild(estilo);

        const bannerCookies = new BannerCookiesTarjetaFlotante({
            posicion: 'abajo-derecha',
            habilitarAnimaciones: true,
            alAceptar: (consentimiento) => {
                console.log('Cookies aceptadas:', consentimiento);

            },
            alRechazar: (consentimiento) => {
                console.log('Cookies rechazadas:', consentimiento);

            },
            alGuardarConfiguracion: (consentimiento) => {
                console.log('Configuración guardada:', consentimiento);

            }
        });

        function mostrarBannerCookies() {
            bannerCookies.resetear();
        }

        function aceptarCookies() {
            bannerCookies.aceptar();
        }

        function rechazarCookies() {
            bannerCookies.rechazar();
        }

        function abrirConfiguracion() {
            bannerCookies.abrirConfiguracion();
        }

        function cerrarConfiguracion() {
            bannerCookies.cerrarConfiguracion();
        }

        function guardarConfiguracion(aceptarTodo) {
            bannerCookies.guardarConfiguracion(aceptarTodo);
        }
    </script>
</body>
</html>

Uso

Implementación Básica


const bannerCookies = new BannerCookiesTarjetaFlotante();

const bannerCookies = new BannerCookiesTarjetaFlotante({
    mostrarAuto: true,
    retrasoMostrar: 2000,
    claveAlmacenamiento: 'mi_consentimiento_cookies',
    diasExpiracion: 180,
    habilitarAnimaciones: true,
    posicion: 'abajo-izquierda',
    alAceptar: (consentimiento) => {
        console.log('Usuario aceptó cookies:', consentimiento);

        if (consentimiento.analiticas) {
            cargarGoogleAnalytics();
        }

        if (consentimiento.marketing) {
            cargarPixelsMarketing();
        }
    },
    alRechazar: (consentimiento) => {
        console.log('Usuario rechazó cookies:', consentimiento);

    },
    alGuardarConfiguracion: (consentimiento) => {
        console.log('Usuario guardó configuración personalizada:', consentimiento);

    }
});

Configuración Avanzada


const bannerAvanzado = new BannerCookiesTarjetaFlotante({
    mostrarAuto: false, // Control manual
    retrasoMostrar: 0,
    claveAlmacenamiento: 'consentimiento_avanzado',
    diasExpiracion: 90,
    habilitarAnimaciones: true,
    posicion: 'arriba-derecha',

    alAceptar: (consentimiento) => {

        inicializarSeguimientoAvanzado(consentimiento);
    },
    
    alRechazar: (consentimiento) => {

        inicializarSoloEsencial();
    },
    
    alGuardarConfiguracion: (consentimiento) => {

        cargarScriptsBasadosEnConsentimiento(consentimiento);
    }
});

function cambiarPosicion(posicion) {
    bannerAvanzado.establecerPosicion(posicion);
}

function alternarAnimaciones(habilitado) {
    bannerAvanzado.habilitarAnimaciones(habilitado);
}

function cambiarTema(tema) {
    bannerAvanzado.actualizarTema(tema);
}

function mostrarBannerConsentimiento() {
    bannerAvanzado.mostrar();
}

function verificarEstadoConsentimiento() {
    const consentimiento = bannerAvanzado.obtenerConsentimiento();
    if (consentimiento) {
        console.log('Consentimiento actual:', consentimiento);
    } else {
        console.log('Aún no se ha dado consentimiento');
    }
}

Métodos de la API

Métodos Principales

  • mostrar() - Mostrar el banner de cookies
  • ocultar() - Ocultar el banner de cookies
  • aceptar() - Aceptar todas las cookies y ocultar banner
  • rechazar() - Rechazar cookies opcionales y ocultar banner
  • resetear() - Limpiar consentimiento almacenado y mostrar banner nuevamente

Gestión de Configuración

  • abrirConfiguracion() - Abrir el modal de configuración
  • cerrarConfiguracion() - Cerrar el modal de configuración
  • guardarConfiguracion(aceptarTodo) - Guardar configuración actual
  • cargarConfiguracion() - Cargar y aplicar configuración almacenada

Gestión de Datos

  • obtenerConsentimiento() - Obtener objeto de consentimiento actual
  • guardarConsentimiento(consentimiento) - Guardar consentimiento en almacenamiento
  • obtenerConsentimientoAlmacenado() - Recuperar consentimiento del almacenamiento

Personalización

  • establecerPosicion(posicion) - Cambiar posición del banner
  • habilitarAnimaciones(habilitado) - Habilitar/deshabilitar animaciones
  • actualizarTema(tema) - Cambiar entre temas claro/oscuro
  • crearOnda(boton) - Crear efectos de onda en botones

Opciones de Personalización

Personalización Visual

  • Esquemas de Color: Modificar propiedades CSS personalizadas para diferentes temas de color
  • Velocidad de Animación: Ajustar duraciones de transición y tiempos de animación
  • Estilo de Tarjeta: Personalizar radio de borde, sombras y espaciado
  • Tipografía: Cambiar familias, tamaños y pesos de fuente

Configuración Funcional

  • Visualización Automática: Controlar aparición automática del banner
  • Duración de Almacenamiento: Establecer período de expiración del consentimiento de cookies
  • Configuración de Retraso: Configurar timing de mostrar/ocultar
  • Funciones de Callback: Manejadores personalizados para acciones del usuario

Características de Accesibilidad

  • Navegación por Teclado: Soporte completo de teclado con indicadores de foco
  • Soporte para Lectores de Pantalla: Etiquetas y descripciones ARIA apropiadas
  • Alto Contraste: Visibilidad mejorada para accesibilidad
  • Gestión de Foco: Captura adecuada de foco en modal

Compatibilidad de Navegadores

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+
  • Navegadores móviles (iOS Safari 12+, Chrome Mobile 60+)

Licencia

Licencia MIT - libre para usar en proyectos personales y comerciales.

HTML

1095

líneas

JavaScript

30

líneas


                <!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Banner de Cookies Tarjeta Flotante</title>
    <style>
        :root {
            --color-primario: #3b82f6;
            --color-primario-hover: #2563eb;
            --color-secundario: #6b7280;
            --color-exito: #10b981;
            --color-exito-hover: #059669;
            --color-peligro: #ef4444;
            --color-peligro-hover: #dc2626;
            --fondo: #ffffff;
            --superficie: #f8fafc;
            --texto-primario: #1f2937;
            --texto-secundario: #6b7280;
            --texto-silenciado: #9ca3af;
            --color-borde: #e5e7eb;
            --sombra-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
            --sombra-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            --sombra-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            --sombra-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
            --radio-borde: 12px;
            --radio-borde-lg: 16px;
            --transicion: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            --transicion-rapida: 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(--texto-primario);
            line-height: 1.6;
            padding: 2rem;
        }

        .contenedor-demo {
            max-width: 1200px;
            margin: 0 auto;
            text-align: center;
            color: white;
        }

        .contenedor-demo 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;
        }

        .contenedor-demo p {
            font-size: 1.2rem;
            opacity: 0.9;
            margin-bottom: 2rem;
        }

        .btn-demo {
            padding: 1rem 2rem;
            border: none;
            border-radius: var(--radio-borde);
            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(--transicion);
            border: 1px solid rgba(255, 255, 255, 0.3);
        }

        .btn-demo:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }.banner-cookies-flotante {
            position: fixed;
            bottom: 2rem;
            right: 2rem;
            width: 420px;
            max-width: calc(100vw - 4rem);
            background: var(--fondo);
            border-radius: var(--radio-borde-lg);
            box-shadow: var(--sombra-xl);
            border: 1px solid var(--color-borde);
            overflow: hidden;
            transform: translateY(120%) scale(0.8);
            opacity: 0;
            transition: var(--transicion);
            z-index: 10000;
            backdrop-filter: blur(20px);
        }

        .banner-cookies-flotante.mostrar {
            transform: translateY(0) scale(1);
            opacity: 1;
        }

        .banner-cookies-flotante:hover {
            transform: translateY(-4px) scale(1.02);
            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
        }

        .encabezado-banner {
            background: linear-gradient(135deg, var(--color-primario) 0%, var(--color-primario-hover) 100%);
            padding: 1.5rem;
            color: white;
            position: relative;
            overflow: hidden;
        }

        .encabezado-banner::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
            animation: brillo 3s infinite;
        }

        @keyframes brillo {
            0% { left: -100%; }
            100% { left: 100%; }
        }

        .icono-banner {
            width: 48px;
            height: 48px;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            margin-bottom: 1rem;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.3);
            animation: flotar 3s ease-in-out infinite;
        }

        @keyframes flotar {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-5px); }
        }

        .titulo-banner {
            font-size: 1.25rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
            position: relative;
            z-index: 1;
        }

        .subtitulo-banner {
            font-size: 0.9rem;
            opacity: 0.9;
            position: relative;
            z-index: 1;
        }

        .contenido-banner {
            padding: 1.5rem;
        }

        .descripcion-cookies {
            color: var(--texto-secundario);
            font-size: 0.95rem;
            line-height: 1.6;
            margin-bottom: 1.5rem;
        }

        .enlace-cookies {
            color: var(--color-primario);
            text-decoration: none;
            font-weight: 600;
            transition: var(--transicion-rapida);
            position: relative;
        }

        .enlace-cookies::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 0;
            height: 2px;
            background: var(--color-primario);
            transition: width 0.3s ease;
        }

        .enlace-cookies:hover {
            color: var(--color-primario-hover);
        }

        .enlace-cookies:hover::after {
            width: 100%;
        }

        .acciones-cookies {
            display: flex;
            gap: 0.75rem;
            margin-top: 1.5rem;
        }.btn-tarjeta {
            flex: 1;
            padding: 0.75rem 1rem;
            border: none;
            border-radius: var(--radio-borde);
            font-family: inherit;
            font-size: 0.9rem;
            font-weight: 600;
            cursor: pointer;
            transition: var(--transicion);
            position: relative;
            overflow: hidden;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .btn-tarjeta::before {
            content: '';
            position: absolute;
            top: 50%;
            left: 50%;
            width: 0;
            height: 0;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
            transform: translate(-50%, -50%);
            transition: width 0.6s ease, height 0.6s ease;
        }

        .btn-tarjeta:hover::before {
            width: 300px;
            height: 300px;
        }

        .btn-aceptar {
            background: var(--color-exito);
            color: white;
            box-shadow: var(--sombra-md);
        }

        .btn-aceptar:hover {
            background: var(--color-exito-hover);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }

        .btn-rechazar {
            background: var(--color-peligro);
            color: white;
            box-shadow: var(--sombra-md);
        }

        .btn-rechazar:hover {
            background: var(--color-peligro-hover);
            transform: translateY(-2px);
            box-shadow: var(--sombra-lg);
        }

        .btn-configuracion {
            background: var(--superficie);
            color: var(--texto-primario);
            border: 1px solid var(--color-borde);
            box-shadow: var(--sombra-sm);
        }

        .btn-configuracion:hover {
            background: var(--color-borde);
            transform: translateY(-2px);
            box-shadow: var(--sombra-md);
        }

        .btn-tarjeta:active {
            transform: translateY(0);
        }.modal-configuracion-cookies {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(8px);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10001;
            opacity: 0;
            visibility: hidden;
            transition: var(--transicion);
        }

        .modal-configuracion-cookies.mostrar {
            opacity: 1;
            visibility: visible;
        }

        .tarjeta-configuracion {
            background: var(--fondo);
            border-radius: var(--radio-borde-lg);
            box-shadow: var(--sombra-xl);
            border: 1px solid var(--color-borde);
            width: 90%;
            max-width: 600px;
            max-height: 80vh;
            overflow: hidden;
            transform: scale(0.9) translateY(20px);
            transition: var(--transicion);
        }

        .modal-configuracion-cookies.mostrar .tarjeta-configuracion {
            transform: scale(1) translateY(0);
        }

        .encabezado-configuracion {
            background: linear-gradient(135deg, var(--color-primario) 0%, var(--color-primario-hover) 100%);
            padding: 2rem;
            color: white;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .titulo-configuracion {
            font-size: 1.5rem;
            font-weight: 700;
        }

        .btn-cerrar {
            width: 40px;
            height: 40px;
            border: none;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.2);
            color: white;
            font-size: 1.25rem;
            cursor: pointer;
            transition: var(--transicion-rapida);
            display: flex;
            align-items: center;
            justify-content: center;
            backdrop-filter: blur(10px);
        }

        .btn-cerrar:hover {
            background: rgba(255, 255, 255, 0.3);
            transform: scale(1.1) rotate(90deg);
        }

        .cuerpo-configuracion {
            padding: 2rem;
            max-height: 60vh;
            overflow-y: auto;
        }

        .categoria-cookies {
            margin-bottom: 2rem;
            padding: 1.5rem;
            background: var(--superficie);
            border: 1px solid var(--color-borde);
            border-radius: var(--radio-borde);
            transition: var(--transicion-rapida);
        }

        .categoria-cookies:hover {
            box-shadow: var(--sombra-md);
            transform: translateY(-1px);
        }

        .encabezado-categoria {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1rem;
        }

        .titulo-categoria {
            font-weight: 700;
            font-size: 1.1rem;
            color: var(--texto-primario);
        }

        .descripcion-categoria {
            font-size: 0.9rem;
            color: var(--texto-secundario);
            line-height: 1.6;
        }.interruptor-tarjeta {
            position: relative;
            width: 56px;
            height: 28px;
            background: var(--color-borde);
            border-radius: 14px;
            cursor: pointer;
            transition: var(--transicion);
            border: 2px solid transparent;
        }

        .interruptor-tarjeta.activo {
            background: var(--color-exito);
            box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
        }

        .interruptor-tarjeta::before {
            content: '';
            position: absolute;
            top: 2px;
            left: 2px;
            width: 20px;
            height: 20px;
            background: white;
            border-radius: 50%;
            transition: var(--transicion);
            box-shadow: var(--sombra-sm);
        }

        .interruptor-tarjeta.activo::before {
            transform: translateX(28px);
            box-shadow: var(--sombra-md);
        }

        .interruptor-tarjeta:hover {
            transform: scale(1.05);
        }

        .acciones-configuracion {
            display: flex;
            gap: 1rem;
            justify-content: flex-end;
            padding: 1.5rem 2rem;
            background: var(--superficie);
            border-top: 1px solid var(--color-borde);
        }@media (max-width: 768px) {
            .banner-cookies-flotante {
                bottom: 1rem;
                right: 1rem;
                left: 1rem;
                width: auto;
                max-width: none;
            }

            .banner-cookies-flotante:hover {
                transform: translateY(-2px) scale(1.01);
            }

            .acciones-cookies {
                flex-direction: column;
            }

            .btn-tarjeta {
                flex: none;
            }

            .tarjeta-configuracion {
                margin: 1rem;
                width: calc(100% - 2rem);
            }

            .encabezado-configuracion {
                padding: 1.5rem;
            }

            .cuerpo-configuracion {
                padding: 1.5rem;
            }

            .acciones-configuracion {
                padding: 1rem 1.5rem;
                flex-direction: column;
            }
        }

        @media (max-width: 480px) {
            body {
                padding: 1rem;
            }

            .contenedor-demo h1 {
                font-size: 2rem;
            }

            .banner-cookies-flotante {
                bottom: 0.5rem;
                right: 0.5rem;
                left: 0.5rem;
            }

            .encabezado-banner {
                padding: 1rem;
            }

            .contenido-banner {
                padding: 1rem;
            }
        }.puntos-carga {
            display: inline-flex;
            gap: 4px;
        }

        .puntos-carga span {
            width: 6px;
            height: 6px;
            background: currentColor;
            border-radius: 50%;
            animation: carga 1.4s infinite ease-in-out;
        }

        .puntos-carga span:nth-child(1) { animation-delay: -0.32s; }
        .puntos-carga span:nth-child(2) { animation-delay: -0.16s; }

        @keyframes carga {
            0%, 80%, 100% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            40% {
                transform: scale(1);
                opacity: 1;
            }
        }.marca-exito {
            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: llenar 0.4s ease-in-out 0.4s forwards, escalar 0.3s ease-in-out 0.9s both;
        }

        .circulo-marca-exito {
            stroke-dasharray: 166;
            stroke-dashoffset: 166;
            stroke-width: 2;
            stroke-miterlimit: 10;
            stroke: currentColor;
            fill: none;
            animation: trazo 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
        }

        .check-marca-exito {
            transform-origin: 50% 50%;
            stroke-dasharray: 48;
            stroke-dashoffset: 48;
            animation: trazo 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
        }

        @keyframes trazo {
            100% {
                stroke-dashoffset: 0;
            }
        }

        @keyframes escalar {
            0%, 100% {
                transform: none;
            }
            50% {
                transform: scale3d(1.1, 1.1, 1);
            }
        }

        @keyframes llenar {
            100% {
                box-shadow: inset 0px 0px 0px 30px currentColor;
            }
        }
    </style>
</head>
<body>
    <div class="contenedor-demo">
        <h1>Diseño de Tarjeta Flotante</h1>
        <p>Experimenta la elegancia del diseño de tarjeta flotante con animaciones suaves e interacciones modernas</p>
        <button class="btn-demo" onclick="mostrarBannerCookies()">Mostrar Banner de Cookies</button>
    </div>

    
    <div id="bannerCookiesFlotante" class="banner-cookies-flotante">
        <div class="encabezado-banner">
            <div class="icono-banner">🍪</div>
            <div class="titulo-banner">Preferencias de Cookies</div>
            <div class="subtitulo-banner">Valoramos tu privacidad</div>
        </div>
        <div class="contenido-banner">
            <div class="descripcion-cookies">
                Utilizamos cookies para mejorar tu experiencia de navegación y proporcionar contenido personalizado. 
                <a href="#" class="enlace-cookies">Política de Privacidad</a> | 
                <a href="#" class="enlace-cookies">Política de Cookies</a>
            </div>
            <div class="acciones-cookies">
                <button class="btn-tarjeta btn-aceptar" onclick="aceptarCookies()">Aceptar Todo</button>
                <button class="btn-tarjeta btn-rechazar" onclick="rechazarCookies()">Rechazar</button>
                <button class="btn-tarjeta btn-configuracion" onclick="abrirConfiguracion()">Personalizar</button>
            </div>
        </div>
    </div>

    
    <div id="modalConfiguracionCookies" class="modal-configuracion-cookies">
        <div class="tarjeta-configuracion">
            <div class="encabezado-configuracion">
                <h3 class="titulo-configuracion">Configuración de Cookies</h3>
                <button class="btn-cerrar" onclick="cerrarConfiguracion()">&times;</button>
            </div>
            <div class="cuerpo-configuracion">
                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies Esenciales</span>
                        <div class="interruptor-tarjeta activo" data-categoria="esenciales"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies son necesarias para que el sitio web funcione y no se pueden desactivar. Generalmente solo se establecen en respuesta a acciones realizadas por ti.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies de Análisis</span>
                        <div class="interruptor-tarjeta" data-categoria="analiticas"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies nos ayudan a entender cómo los visitantes interactúan con nuestro sitio web recopilando y reportando información de forma anónima.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies de Marketing</span>
                        <div class="interruptor-tarjeta" data-categoria="marketing"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies se utilizan para entregar anuncios más relevantes para ti y tus intereses basados en tu comportamiento de navegación.
                    </div>
                </div>

                <div class="categoria-cookies">
                    <div class="encabezado-categoria">
                        <span class="titulo-categoria">Cookies Funcionales</span>
                        <div class="interruptor-tarjeta" data-categoria="funcionales"></div>
                    </div>
                    <div class="descripcion-categoria">
                        Estas cookies habilitan funcionalidad mejorada y personalización, como recordar tus preferencias y configuraciones.
                    </div>
                </div>
            </div>
            <div class="acciones-configuracion">
                <button class="btn-tarjeta btn-rechazar" onclick="guardarConfiguracion(false)">Guardar Preferencias</button>
                <button class="btn-tarjeta btn-aceptar" onclick="guardarConfiguracion(true)">Aceptar Todo</button>
            </div>
        </div>
    </div>

    <script>
        class BannerCookiesTarjetaFlotante {
            constructor(opciones = {}) {
                this.opciones = {
                    mostrarAuto: true,
                    retrasoMostrar: 1500,
                    claveAlmacenamiento: 'consentimiento_cookies_tarjeta_flotante',
                    diasExpiracion: 365,
                    habilitarAnimaciones: true,
                    posicion: 'abajo-derecha',
                    alAceptar: null,
                    alRechazar: null,
                    alGuardarConfiguracion: null,
                    ...opciones
                };

                this.banner = document.getElementById('bannerCookiesFlotante');
                this.modal = document.getElementById('modalConfiguracionCookies');
                this.consentimiento = this.obtenerConsentimientoAlmacenado();
                this.esVisible = false;

                this.inicializar();
            }

            inicializar() {
                if (this.opciones.mostrarAuto && !this.consentimiento) {
                    setTimeout(() => this.mostrar(), this.opciones.retrasoMostrar);
                }

                this.configurarEventListeners();
                this.cargarConfiguracion();
                this.configurarPosicion();
            }

            configurarEventListeners() {

                document.querySelectorAll('.interruptor-tarjeta').forEach(interruptor => {
                    interruptor.addEventListener('click', () => {
                        if (interruptor.dataset.categoria !== 'esenciales') {
                            interruptor.classList.toggle('activo');
                            this.animarInterruptor(interruptor);
                        }
                    });
                });

                this.modal.addEventListener('click', (e) => {
                    if (e.target === this.modal) {
                        this.cerrarConfiguracion();
                    }
                });

                document.addEventListener('keydown', (e) => {
                    if (e.key === 'Escape') {
                        this.cerrarConfiguracion();
                    }
                });

                document.querySelectorAll('.btn-tarjeta').forEach(btn => {
                    btn.addEventListener('mouseenter', () => {
                        this.crearOnda(btn);
                    });
                });

                this.banner.addEventListener('mouseenter', () => {
                    if (this.esVisible) {
                        this.mejorarEfectoHover();
                    }
                });

                this.banner.addEventListener('mouseleave', () => {
                    if (this.esVisible) {
                        this.resetearEfectoHover();
                    }
                });
            }

            configurarPosicion() {
                const posiciones = {
                    'abajo-derecha': { bottom: '2rem', right: '2rem', left: 'auto', top: 'auto' },
                    'abajo-izquierda': { bottom: '2rem', left: '2rem', right: 'auto', top: 'auto' },
                    'arriba-derecha': { top: '2rem', right: '2rem', left: 'auto', bottom: 'auto' },
                    'arriba-izquierda': { top: '2rem', left: '2rem', right: 'auto', bottom: 'auto' }
                };

                const pos = posiciones[this.opciones.posicion] || posiciones['abajo-derecha'];
                Object.assign(this.banner.style, pos);
            }

            animarInterruptor(interruptor) {
                if (!this.opciones.habilitarAnimaciones) return;

                interruptor.style.transform = 'scale(0.9)';
                setTimeout(() => {
                    interruptor.style.transform = 'scale(1)';
                }, 150);

                interruptor.style.boxShadow = '0 0 0 8px rgba(16, 185, 129, 0.2)';
                setTimeout(() => {
                    interruptor.style.boxShadow = '';
                }, 300);
            }

            crearOnda(boton) {
                if (!this.opciones.habilitarAnimaciones) return;

                const onda = document.createElement('span');
                const rect = boton.getBoundingClientRect();
                const tamaño = Math.max(rect.width, rect.height);
                
                onda.style.width = onda.style.height = tamaño + 'px';
                onda.style.left = '50%';
                onda.style.top = '50%';
                onda.style.transform = 'translate(-50%, -50%) scale(0)';
                onda.style.position = 'absolute';
                onda.style.borderRadius = '50%';
                onda.style.background = 'rgba(255, 255, 255, 0.3)';
                onda.style.pointerEvents = 'none';
                onda.style.animation = 'onda 0.6s ease-out';
                
                boton.style.position = 'relative';
                boton.style.overflow = 'hidden';
                boton.appendChild(onda);
                
                setTimeout(() => {
                    onda.remove();
                }, 600);
            }

            mejorarEfectoHover() {
                if (!this.opciones.habilitarAnimaciones) return;
                
                const icono = this.banner.querySelector('.icono-banner');
                if (icono) {
                    icono.style.transform = 'scale(1.1) rotate(5deg)';
                }
            }

            resetearEfectoHover() {
                if (!this.opciones.habilitarAnimaciones) return;
                
                const icono = this.banner.querySelector('.icono-banner');
                if (icono) {
                    icono.style.transform = '';
                }
            }

            mostrar() {
                this.banner.classList.add('mostrar');
                this.esVisible = true;
                
                if (this.opciones.habilitarAnimaciones) {
                    this.animarEntrada();
                }
            }

            ocultar() {
                this.banner.classList.remove('mostrar');
                this.esVisible = false;
            }

            animarEntrada() {
                const elementos = [
                    this.banner.querySelector('.icono-banner'),
                    this.banner.querySelector('.titulo-banner'),
                    this.banner.querySelector('.subtitulo-banner'),
                    this.banner.querySelector('.descripcion-cookies'),
                    this.banner.querySelector('.acciones-cookies')
                ];

                elementos.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);
                    }
                });
            }

            aceptar() {
                const consentimiento = {
                    esenciales: true,
                    analiticas: true,
                    marketing: true,
                    funcionales: true,
                    marcaTiempo: Date.now()
                };

                this.guardarConsentimiento(consentimiento);
                this.mostrarAnimacionExito();
                
                setTimeout(() => {
                    this.ocultar();
                }, 1500);

                if (this.opciones.alAceptar) {
                    this.opciones.alAceptar(consentimiento);
                }
            }

            rechazar() {
                const consentimiento = {
                    esenciales: true,
                    analiticas: false,
                    marketing: false,
                    funcionales: false,
                    marcaTiempo: Date.now()
                };

                this.guardarConsentimiento(consentimiento);
                this.ocultar();

                if (this.opciones.alRechazar) {
                    this.opciones.alRechazar(consentimiento);
                }
            }

            mostrarAnimacionExito() {
                if (!this.opciones.habilitarAnimaciones) return;

                const btnAceptar = this.banner.querySelector('.btn-aceptar');
                if (btnAceptar) {
                    btnAceptar.innerHTML = `
                        <svg class="marca-exito" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
                            <circle class="circulo-marca-exito" cx="26" cy="26" r="25" fill="none"/>
                            <path class="check-marca-exito" fill="none" d="m14.1 27.2l7.1 7.2 16.7-16.8"/>
                        </svg>
                        Aceptado
                    `;
                    btnAceptar.style.background = 'var(--color-exito)';
                }
            }

            abrirConfiguracion() {
                this.modal.classList.add('mostrar');
                document.body.style.overflow = 'hidden';
                
                if (this.opciones.habilitarAnimaciones) {
                    this.animarEntradaModal();
                }
            }

            cerrarConfiguracion() {
                this.modal.classList.remove('mostrar');
                document.body.style.overflow = '';
            }

            animarEntradaModal() {
                const categorias = this.modal.querySelectorAll('.categoria-cookies');
                categorias.forEach((categoria, index) => {
                    categoria.style.opacity = '0';
                    categoria.style.transform = 'translateX(-20px)';
                    
                    setTimeout(() => {
                        categoria.style.transition = 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)';
                        categoria.style.opacity = '1';
                        categoria.style.transform = 'translateX(0)';
                    }, index * 100);
                });
            }

            guardarConfiguracion(aceptarTodo = false) {
                const interruptores = document.querySelectorAll('.interruptor-tarjeta');
                const consentimiento = { marcaTiempo: Date.now() };

                interruptores.forEach(interruptor => {
                    const categoria = interruptor.dataset.categoria;
                    if (aceptarTodo) {
                        consentimiento[categoria] = true;
                        interruptor.classList.add('activo');
                    } else {
                        consentimiento[categoria] = interruptor.classList.contains('activo');
                    }
                });

                this.guardarConsentimiento(consentimiento);
                this.cerrarConfiguracion();
                this.ocultar();

                if (this.opciones.alGuardarConfiguracion) {
                    this.opciones.alGuardarConfiguracion(consentimiento);
                }
            }

            cargarConfiguracion() {
                if (this.consentimiento) {
                    document.querySelectorAll('.interruptor-tarjeta').forEach(interruptor => {
                        const categoria = interruptor.dataset.categoria;
                        if (this.consentimiento[categoria]) {
                            interruptor.classList.add('activo');
                        } else {
                            interruptor.classList.remove('activo');
                        }
                    });
                }
            }

            guardarConsentimiento(consentimiento) {
                const fechaExpiracion = new Date();
                fechaExpiracion.setDate(fechaExpiracion.getDate() + this.opciones.diasExpiracion);
                
                const datosConsentimiento = {
                    ...consentimiento,
                    expiracion: fechaExpiracion.getTime()
                };

                localStorage.setItem(this.opciones.claveAlmacenamiento, JSON.stringify(datosConsentimiento));
                this.consentimiento = consentimiento;
            }

            obtenerConsentimientoAlmacenado() {
                try {
                    const almacenado = localStorage.getItem(this.opciones.claveAlmacenamiento);
                    if (almacenado) {
                        const datos = JSON.parse(almacenado);
                        if (datos.expiracion && Date.now() < datos.expiracion) {
                            return datos;
                        } else {
                            localStorage.removeItem(this.opciones.claveAlmacenamiento);
                        }
                    }
                } catch (e) {
                    console.error('Error al leer el consentimiento de cookies:', e);
                }
                return null;
            }

            resetear() {
                localStorage.removeItem(this.opciones.claveAlmacenamiento);
                this.consentimiento = null;
                this.mostrar();
            }

            obtenerConsentimiento() {
                return this.consentimiento;
            }

            establecerPosicion(posicion) {
                this.opciones.posicion = posicion;
                this.configurarPosicion();
            }

            habilitarAnimaciones(habilitado) {
                this.opciones.habilitarAnimaciones = habilitado;
            }

            actualizarTema(tema) {
                const temas = {
                    claro: {
                        '--fondo': '#ffffff',
                        '--superficie': '#f8fafc',
                        '--texto-primario': '#1f2937',
                        '--texto-secundario': '#6b7280'
                    },
                    oscuro: {
                        '--fondo': '#1f2937',
                        '--superficie': '#374151',
                        '--texto-primario': '#f9fafb',
                        '--texto-secundario': '#d1d5db'
                    }
                };

                if (temas[tema]) {
                    Object.entries(temas[tema]).forEach(([propiedad, valor]) => {
                        document.documentElement.style.setProperty(propiedad, valor);
                    });
                }
            }
        }

        const estilo = document.createElement('style');
        estilo.textContent = `
            @keyframes onda {
                to {
                    transform: translate(-50%, -50%) scale(2);
                    opacity: 0;
                }
            }
        `;
        document.head.appendChild(estilo);

        const bannerCookies = new BannerCookiesTarjetaFlotante({
            posicion: 'abajo-derecha',
            habilitarAnimaciones: true,
            alAceptar: (consentimiento) => {
                console.log('Cookies aceptadas:', consentimiento);

            },
            alRechazar: (consentimiento) => {
                console.log('Cookies rechazadas:', consentimiento);

            },
            alGuardarConfiguracion: (consentimiento) => {
                console.log('Configuración guardada:', consentimiento);

            }
        });

        function mostrarBannerCookies() {
            bannerCookies.resetear();
        }

        function aceptarCookies() {
            bannerCookies.aceptar();
        }

        function rechazarCookies() {
            bannerCookies.rechazar();
        }

        function abrirConfiguracion() {
            bannerCookies.abrirConfiguracion();
        }

        function cerrarConfiguracion() {
            bannerCookies.cerrarConfiguracion();
        }

        function guardarConfiguracion(aceptarTodo) {
            bannerCookies.guardarConfiguracion(aceptarTodo);
        }
    </script>
</body>
</html>

              
1095líneas
37052caracteres
HTMLIdioma

Fragmentos de Código Relacionados

Explora packs de plantillas

¿Necesitas bloques más grandes? Descubre landings y colecciones de componentes.

Abrir la biblioteca de plantillas ->