Template E-commerce HTML CSS JS

Extraits & Composants HTML 30/03/2026 20:00:00 AngularForAll.com
Html5 Css3 Javascript E Commerce Template Panier Dynamique Filtres Responsive Vanilla Js Boutique

Template e-commerce interactif en HTML5, CSS3 et JavaScript vanilla avec panier dynamique, filtres produits en temps réel et animations.

<!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>Template E Commerce HTML CSS JS 2026 04291651 | AngularForAll</title>
<style>
        /* Reset & Variables */
        :root {
            --primary: #2563eb;
            --primary-dark: #1d4ed8;
            --secondary: #10b981;
            --dark: #1e293b;
            --light: #f8fafc;
            --gray: #64748b;
            --gray-light: #e2e8f0;
            --white: #ffffff;
            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
            --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
            --radius: 12px;
            --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            background: var(--light);
            color: var(--dark);
            line-height: 1.6;
        }

        /* Header & Navigation */
        .header {
            background: var(--white);
            box-shadow: var(--shadow);
            position: sticky;
            top: 0;
            z-index: 1000;
            backdrop-filter: blur(10px);
        }

        .nav {
            max-width: 1400px;
            margin: 0 auto;
            padding: 1rem 2rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .logo {
            font-size: 1.8rem;
            font-weight: 800;
            color: var(--primary);
            text-decoration: none;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .logo span {
            background: var(--primary);
            color: white;
            padding: 0.3rem 0.8rem;
            border-radius: 8px;
            font-size: 1rem;
        }

        .nav-links {
            display: flex;
            list-style: none;
            gap: 2rem;
            align-items: center;
        }

        .nav-links a {
            text-decoration: none;
            color: var(--dark);
            font-weight: 500;
            transition: var(--transition);
            position: relative;
        }

        .nav-links a::after {
            content: '';
            position: absolute;
            bottom: -5px;
            left: 0;
            width: 0;
            height: 2px;
            background: var(--primary);
            transition: var(--transition);
        }

        .nav-links a:hover::after {
            width: 100%;
        }

        .cart-icon {
            background: var(--primary);
            color: white;
            padding: 0.5rem 1rem;
            border-radius: 50px;
            cursor: pointer;
            position: relative;
            border: none;
            font-size: 1rem;
            transition: var(--transition);
        }

        .cart-icon:hover {
            background: var(--primary-dark);
            transform: translateY(-2px);
        }

        .cart-count {
            background: var(--secondary);
            color: white;
            border-radius: 50%;
            padding: 0.2rem 0.5rem;
            font-size: 0.8rem;
            margin-left: 0.5rem;
        }

        .menu-toggle {
            display: none;
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: var(--dark);
        }

        /* Hero Section */
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 4rem 2rem;
            text-align: center;
            margin-bottom: 2rem;
        }

        .hero h1 {
            font-size: 3rem;
            margin-bottom: 1rem;
            animation: fadeInUp 0.8s ease;
        }

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

        .hero-btn {
            background: white;
            color: var(--primary);
            padding: 1rem 2rem;
            border: none;
            border-radius: 50px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: var(--transition);
            text-decoration: none;
            display: inline-block;
        }

        .hero-btn:hover {
            transform: translateY(-3px);
            box-shadow: var(--shadow-lg);
        }

        /* Main Content */
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 0 2rem;
        }

        .filters {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 2rem;
            flex-wrap: wrap;
            gap: 1rem;
        }

        .search-bar {
            display: flex;
            gap: 1rem;
            flex: 1;
            max-width: 500px;
        }

        .search-bar input {
            flex: 1;
            padding: 0.8rem 1.2rem;
            border: 2px solid var(--gray-light);
            border-radius: 50px;
            font-size: 1rem;
            transition: var(--transition);
            background: var(--white);
        }

        .search-bar input:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
        }

        .category-filters {
            display: flex;
            gap: 1rem;
            flex-wrap: wrap;
        }

        .filter-btn {
            padding: 0.6rem 1.5rem;
            border: 2px solid var(--gray-light);
            border-radius: 50px;
            background: var(--white);
            cursor: pointer;
            transition: var(--transition);
            font-weight: 500;
            color: var(--dark);
        }

        .filter-btn.active {
            background: var(--primary);
            color: white;
            border-color: var(--primary);
        }

        .filter-btn:hover {
            border-color: var(--primary);
            color: var(--primary);
        }

        /* Products Grid */
        .products-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 2rem;
            margin-bottom: 3rem;
        }

        .product-card {
            background: var(--white);
            border-radius: var(--radius);
            overflow: hidden;
            box-shadow: var(--shadow);
            transition: var(--transition);
            display: flex;
            flex-direction: column;
        }

        .product-card:hover {
            transform: translateY(-5px);
            box-shadow: var(--shadow-lg);
        }

        .product-image {
            position: relative;
            overflow: hidden;
            height: 250px;
            background: linear-gradient(45deg, #f3f4f6, #e5e7eb);
        }

        .product-image img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: var(--transition);
        }

        .product-card:hover .product-image img {
            transform: scale(1.1);
        }

        .badge {
            position: absolute;
            top: 1rem;
            right: 1rem;
            background: var(--secondary);
            color: white;
            padding: 0.3rem 0.8rem;
            border-radius: 50px;
            font-size: 0.9rem;
            font-weight: 600;
        }

        .product-info {
            padding: 1.5rem;
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        .product-category {
            color: var(--gray);
            font-size: 0.9rem;
            margin-bottom: 0.5rem;
        }

        .product-name {
            font-size: 1.2rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
        }

        .product-description {
            color: var(--gray);
            font-size: 0.9rem;
            margin-bottom: 1rem;
        }

        .product-rating {
            color: #f59e0b;
            margin-bottom: 0.5rem;
        }

        .product-price {
            font-size: 1.5rem;
            font-weight: 700;
            color: var(--primary);
            margin-bottom: 1rem;
        }

        .add-to-cart {
            background: var(--primary);
            color: white;
            border: none;
            padding: 0.8rem;
            border-radius: 8px;
            cursor: pointer;
            transition: var(--transition);
            font-weight: 600;
            font-size: 1rem;
            margin-top: auto;
        }

        .add-to-cart:hover {
            background: var(--primary-dark);
            transform: translateY(-2px);
        }

        /* Modal */
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 2000;
            align-items: center;
            justify-content: center;
            backdrop-filter: blur(5px);
        }

        .modal.active {
            display: flex;
        }

        .modal-content {
            background: var(--white);
            padding: 2rem;
            border-radius: var(--radius);
            max-width: 500px;
            width: 90%;
            animation: slideUp 0.3s ease;
            max-height: 80vh;
            overflow-y: auto;
        }

        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1.5rem;
        }

        .close-modal {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: var(--gray);
        }

        .cart-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem 0;
            border-bottom: 1px solid var(--gray-light);
        }

        .cart-total {
            font-size: 1.3rem;
            font-weight: 700;
            text-align: right;
            margin: 1.5rem 0;
        }

        .checkout-btn {
            width: 100%;
            background: var(--secondary);
            color: white;
            border: none;
            padding: 1rem;
            border-radius: 8px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: var(--transition);
        }

        .checkout-btn:hover {
            background: #059669;
        }

        .remove-item {
            background: #ef4444;
            color: white;
            border: none;
            padding: 0.4rem 0.8rem;
            border-radius: 6px;
            cursor: pointer;
            font-size: 0.9rem;
        }

        /* Toast Notification */
        .toast {
            position: fixed;
            top: 20px;
            right: 20px;
            background: var(--secondary);
            color: white;
            padding: 1rem 2rem;
            border-radius: 8px;
            box-shadow: var(--shadow-lg);
            transform: translateX(400px);
            transition: var(--transition);
            z-index: 3000;
        }

        .toast.show {
            transform: translateX(0);
        }

        /* Animations */
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        @keyframes slideUp {
            from {
                transform: translateY(50px);
                opacity: 0;
            }
            to {
                transform: translateY(0);
                opacity: 1;
            }
        }

        .hidden {
            display: none;
        }

        /* Responsive Design */
        @media (max-width: 768px) {
            .nav {
                flex-wrap: wrap;
                padding: 1rem;
            }

            .menu-toggle {
                display: block;
                order: 3;
            }

            .nav-links {
                display: none;
                width: 100%;
                flex-direction: column;
                padding: 1rem 0;
                gap: 1rem;
            }

            .nav-links.active {
                display: flex;
            }

            .hero h1 {
                font-size: 2rem;
            }

            .hero p {
                font-size: 1rem;
            }

            .products-grid {
                grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
                gap: 1rem;
            }

            .filters {
                flex-direction: column;
                align-items: stretch;
            }

            .search-bar {
                max-width: 100%;
            }

            .category-filters {
                overflow-x: auto;
                flex-wrap: nowrap;
                padding-bottom: 0.5rem;
            }

            .filter-btn {
                white-space: nowrap;
                flex-shrink: 0;
            }
        }

        @media (max-width: 480px) {
            .products-grid {
                grid-template-columns: 1fr;
            }

            .hero {
                padding: 2rem 1rem;
            }

            .container {
                padding: 0 1rem;
            }
        }
    </style>
</head>
<body>
    <!-- Header -->
    <header class="header">
        <nav class="nav">
            <a href="#" class="logo">
                Shop<span>Moderne</span>
            </a>

            <button class="menu-toggle" aria-label="Menu">
                ☰
            </button>

            <ul class="nav-links">
                <li><a href="#">Accueil</a></li>
                <li><a href="#">Produits</a></li>
                <li><a href="#">À propos</a></li>
                <li><a href="#">Contact</a></li>
                <li>
                    <button class="cart-icon" aria-label="Panier">
                        🛒 Panier <span class="cart-count" id="cartCount">0</span>
                    </button>
                </li>
            </ul>
        </nav>
    </header>

    <!-- Hero Section -->
    <section class="hero">
        <h1>Collection Moderne</h1>
        <p>Découvrez notre sélection de produits tendance à prix imbattables</p>
        <a href="#products" class="hero-btn">Voir les produits</a>
    </section>

    <!-- Main Content -->
    <main class="container" id="products">
        <!-- Filters -->
        <div class="filters">
            <div class="search-bar">
                <input type="text" id="searchInput" placeholder="Rechercher un produit...">
            </div>
            <div class="category-filters">
                <button class="filter-btn active" data-category="all">Tout</button>
                <button class="filter-btn" data-category="electronique">Électronique</button>
                <button class="filter-btn" data-category="mode">Mode</button>
                <button class="filter-btn" data-category="maison">Maison</button>
            </div>
        </div>

        <!-- Products Grid -->
        <div class="products-grid" id="productsGrid">
            <!-- Produits générés par JavaScript -->
        </div>
    </main>

    <!-- Cart Modal -->
    <div class="modal" id="cartModal">
        <div class="modal-content">
            <div class="modal-header">
                <h2>🛒 Votre Panier</h2>
                <button class="close-modal" aria-label="Fermer">&times;</button>
            </div>
            <div id="cartItems">
                <p style="text-align: center; color: var(--gray);">Votre panier est vide</p>
            </div>
            <div class="cart-total" id="cartTotal">Total: 0€</div>
            <button class="checkout-btn" onclick="checkout()">Passer la commande</button>
        </div>
    </div>

    <!-- Toast Notification -->
    <div class="toast" id="toast"></div>

    <script>
        // Données des produits
        const products = [
            {
                id: 1,
                name: "Smartphone Pro X",
                category: "electronique",
                price: 799.99,
                rating: 4.5,
                description: "Dernier cri de la technologie avec appareil photo 108MP",
                image: "public/phoneL.webp",
                badge: "Nouveau"
            },
            {
                id: 2,
                name: "Écouteurs Sans Fil",
                category: "electronique",
                price: 149.99,
                rating: 4.8,
                description: "Son haute fidélité avec réduction de bruit active",
                image: "public/baff.webp",
                badge: "Best Seller"
            },
            {
                id: 3,
                name: "Montre Connectée",
                category: "electronique",
                price: 299.99,
                rating: 4.3,
                description: "Suivi santé, notifications et design élégant",
                image: "public/smartwash.webp"
            },
            {
                id: 4,
                name: "Sac à Main Élégant",
                category: "mode",
                price: 89.99,
                rating: 4.6,
                description: "Cuir véritable, design intemporel",
                image: "public/baff.webp",
                badge: "Promo"
            },
            {
                id: 5,
                name: "Baskets Tendance",
                category: "mode",
                price: 129.99,
                rating: 4.7,
                description: "Confort et style pour tous les jours",
                image: "public/ordinateur-portable-laptop.webp"
            },
            {
                id: 6,
                name: "Lampe Design",
                category: "maison",
                price: 59.99,
                rating: 4.4,
                description: "Éclairage LED intelligent pour votre intérieur",
                image: "public/mobile2.png"
            },
            {
                id: 7,
                name: "Tablette Tactile",
                category: "electronique",
                price: 449.99,
                rating: 4.2,
                description: "Parfaite pour le travail et les loisirs",
                image: "public/phoneL.webp",
                badge: "Populaire"
            },
            {
                id: 8,
                name: "Plaid Confort",
                category: "maison",
                price: 39.99,
                rating: 4.9,
                description: "Doux et chaud, idéal pour les soirées cocooning",
                image: "public/mobile4.png"
            }
        ];

        // État de l'application
        let cart = [];
        let currentFilter = 'all';

        // Initialisation
        function init() {
            displayProducts(products);
            setupEventListeners();
        }

        // Affichage des produits
        function displayProducts(productsToShow) {
            const grid = document.getElementById('productsGrid');

            if (productsToShow.length === 0) {
                grid.innerHTML = '<p style="text-align: center; grid-column: 1/-1; color: var(--gray); font-size: 1.2rem;">Aucun produit trouvé</p>';
                return;
            }

            grid.innerHTML = productsToShow.map(product => `
                <article class="product-card" data-category="${product.category}">
                    <div class="product-image">
                        <img src="${product.image}" alt="${product.name}" loading="lazy">
                        ${product.badge ? `<span class="badge">${product.badge}</span>` : ''}
                    </div>
                    <div class="product-info">
                        <span class="product-category">${product.category}</span>
                        <h3 class="product-name">${product.name}</h3>
                        <p class="product-description">${product.description}</p>
                        <div class="product-rating">
                            ${generateStars(product.rating)}
                            <span style="color: var(--gray); margin-left: 0.5rem;">${product.rating}</span>
                        </div>
                        <div class="product-price">${product.price.toFixed(2)}€</div>
                        <button class="add-to-cart" onclick="addToCart(${product.id})">
                            Ajouter au panier
                        </button>
                    </div>
                </article>
            `).join('');
        }

        // Génération des étoiles
        function generateStars(rating) {
            const fullStars = Math.floor(rating);
            const halfStar = rating % 1 >= 0.5;
            const emptyStars = 5 - fullStars - (halfStar ? 1 : 0);

            return '★'.repeat(fullStars) + (halfStar ? '½' : '') + '☆'.repeat(emptyStars);
        }

        // Ajout au panier
        function addToCart(productId) {
            const product = products.find(p => p.id === productId);
            const existingItem = cart.find(item => item.id === productId);

            if (existingItem) {
                existingItem.quantity++;
            } else {
                cart.push({
                    ...product,
                    quantity: 1
                });
            }

            updateCartCount();
            showToast(`${product.name} ajouté au panier !`);

            // Animation du bouton
            const buttons = document.querySelectorAll('.add-to-cart');
            buttons.forEach(btn => {
                btn.style.transform = 'scale(0.95)';
                setTimeout(() => {
                    btn.style.transform = 'scale(1)';
                }, 100);
            });
        }

        // Mise à jour du compteur du panier
        function updateCartCount() {
            const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0);
            document.getElementById('cartCount').textContent = totalItems;
        }

        // Affichage du panier
        function displayCart() {
            const cartItems = document.getElementById('cartItems');
            const cartTotal = document.getElementById('cartTotal');

            if (cart.length === 0) {
                cartItems.innerHTML = '<p style="text-align: center; color: var(--gray);">Votre panier est vide</p>';
                cartTotal.textContent = 'Total: 0€';
                return;
            }

            cartItems.innerHTML = cart.map(item => `
                <div class="cart-item">
                    <div>
                        <strong>${item.name}</strong>
                        <br>
                        <small>Quantité: ${item.quantity} × ${item.price.toFixed(2)}€</small>
                    </div>
                    <div>
                        <span style="font-weight: 600;">${(item.price * item.quantity).toFixed(2)}€</span>
                        <button class="remove-item" onclick="removeFromCart(${item.id})">Supprimer</button>
                    </div>
                </div>
            `).join('');

            const total = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
            cartTotal.textContent = `Total: ${total.toFixed(2)}€`;
        }

        // Suppression du panier
        function removeFromCart(productId) {
            cart = cart.filter(item => item.id !== productId);
            updateCartCount();
            displayCart();
            showToast('Produit retiré du panier');
        }

        // Toast notification
        function showToast(message) {
            const toast = document.getElementById('toast');
            toast.textContent = message;
            toast.classList.add('show');

            setTimeout(() => {
                toast.classList.remove('show');
            }, 3000);
        }

        // Filtrage des produits
        function filterProducts(category) {
            currentFilter = category;

            // Mise à jour des boutons actifs
            document.querySelectorAll('.filter-btn').forEach(btn => {
                btn.classList.remove('active');
                if (btn.dataset.category === category) {
                    btn.classList.add('active');
                }
            });

            // Filtrer et afficher
            const searchTerm = document.getElementById('searchInput').value.toLowerCase();
            let filtered = category === 'all' ? [...products] : products.filter(p => p.category === category);

            if (searchTerm) {
                filtered = filtered.filter(p =>
                    p.name.toLowerCase().includes(searchTerm) ||
                    p.description.toLowerCase().includes(searchTerm) ||
                    p.category.toLowerCase().includes(searchTerm)
                );
            }

            // Animation de transition
            const grid = document.getElementById('productsGrid');
            grid.style.opacity = '0';
            grid.style.transform = 'translateY(20px)';
            grid.style.transition = 'all 0.3s ease';

            setTimeout(() => {
                displayProducts(filtered);
                grid.style.opacity = '1';
                grid.style.transform = 'translateY(0)';
            }, 300);
        }

        // Recherche
        function searchProducts() {
            filterProducts(currentFilter);
        }

        // Checkout
        function checkout() {
            if (cart.length === 0) {
                showToast('Votre panier est vide !');
                return;
            }

            showToast('Commande validée avec succès ! Merci de votre achat.');
            cart = [];
            updateCartCount();
            displayCart();
            document.getElementById('cartModal').classList.remove('active');
        }

        // Configuration des événements
        function setupEventListeners() {
            // Menu mobile
            const menuToggle = document.querySelector('.menu-toggle');
            const navLinks = document.querySelector('.nav-links');

            menuToggle.addEventListener('click', () => {
                navLinks.classList.toggle('active');
            });

            // Fermer le menu mobile en cliquant sur un lien
            navLinks.querySelectorAll('a').forEach(link => {
                link.addEventListener('click', () => {
                    navLinks.classList.remove('active');
                });
            });

            // Modal du panier
            const cartIcon = document.querySelector('.cart-icon');
            const cartModal = document.getElementById('cartModal');
            const closeModal = document.querySelector('.close-modal');

            cartIcon.addEventListener('click', () => {
                displayCart();
                cartModal.classList.add('active');
            });

            closeModal.addEventListener('click', () => {
                cartModal.classList.remove('active');
            });

            cartModal.addEventListener('click', (e) => {
                if (e.target === cartModal) {
                    cartModal.classList.remove('active');
                }
            });

            // Filtres de catégorie
            document.querySelectorAll('.filter-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    filterProducts(btn.dataset.category);
                });
            });

            // Recherche avec debounce
            let searchTimeout;
            document.getElementById('searchInput').addEventListener('input', () => {
                clearTimeout(searchTimeout);
                searchTimeout = setTimeout(searchProducts, 300);
            });

            // Fermer le menu mobile en cliquant en dehors
            document.addEventListener('click', (e) => {
                if (!e.target.closest('.nav') && navLinks.classList.contains('active')) {
                    navLinks.classList.remove('active');
                }
            });
        }

        // Démarrage de l'application
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>

Télécharger le fichier source

Partager