logo oujood
🔍

🎨 Style CSS pour le panier e-commerce

Dans ce chapitre, nous allons appliquer un style **simple, clair et responsive** à notre panier. Cela va :

OUJOOD.COM

💅 0. Feuille de style CSS minimale

  • Améliorer la lisibilité des produits
  • Clarifier les boutons ➕ ➖ ❌
  • Structurer l’affichage total et alertes

📋 Copier le code

<style>
  body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    padding: 20px;
    max-width: 600px;
    margin: auto;
  }

  h1 {
    text-align: center;
    color: #333;
  }

  .produit {
    background: #fff;
    padding: 12px;
    border-radius: 8px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.1);
    margin-bottom: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .produit-info {
    flex: 1;
  }

  .boutons {
    display: flex;
    gap: 5px;
  }

  button {
    padding: 5px 10px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  button:hover {
    background-color: #eee;
  }

  #total {
    font-weight: bold;
    font-size: 18px;
  }

  #alerte {
    color: red;
    font-weight: bold;
    text-align: center;
    margin-top: 10px;
  }
</style>
  • Le style applique un **fond clair**, une **ombre douce**, et un **alignement propre** des éléments
  • Les boutons ont un **effet au survol** pour améliorer l’interactivité

📦 1. Structure HTML de base

📋 Copier le code

<div id="liste-produits"></div>
<p><strong>Total :</strong> <span id="total">0 €</span></p>
<div id="alerte"></div>
  • liste-produits : contiendra tous les articles
  • total : affiche la somme du panier
  • alerte : pour les erreurs comme le dépassement du stock

🔧 2. Classe Produit

📋 Copier le code

class Produit {
  constructor(id, nom, prix, stock, description) {
    this.id = id;
    this.nom = nom;
    this.prix = prix;
    this.stock = stock;
    this.description = description;
  }
}

Représente chaque article du panier, avec ses informations de base.

🧠 3. Classe Panier avec affichage stylé

📋 Copier le code

class Panier {
  constructor() {
    const sauvegarde = localStorage.getItem("monPanier");
    this.elements = sauvegarde ? JSON.parse(sauvegarde) : [];
    this.actualiserAffichage();
  }

  sauvegarder() {
    localStorage.setItem("monPanier", JSON.stringify(this.elements));
  }

  ajouterProduit(produit) {
    const ligne = this.elements.find(p => p.produit.id === produit.id);
    const alerte = document.getElementById("alerte");
    alerte.textContent = "";

    if (ligne) {
      if (ligne.quantite >= produit.stock) {
        alerte.textContent = \`❌ Stock insuffisant pour \${produit.nom}\`;
        return;
      }
      ligne.quantite++;
    } else {
      if (produit.stock < 1) {
        alerte.textContent = \`❌ Produit \${produit.nom} en rupture de stock\`;
        return;
      }
      this.elements.push({ produit, quantite: 1 });
    }

    this.sauvegarder();
    this.actualiserAffichage();
  }

  changerQuantite(id, operation) {
    const ligne = this.elements.find(p => p.produit.id === id);
    if (!ligne) return;

    const alerte = document.getElementById("alerte");
    alerte.textContent = "";

    if (operation === "plus") {
      if (ligne.quantite >= ligne.produit.stock) {
        alerte.textContent = \`❌ Stock max atteint pour \${ligne.produit.nom}\`;
        return;
      }
      ligne.quantite++;
    } else if (operation === "moins") {
      if (ligne.quantite > 1) {
        ligne.quantite--;
      } else {
        this.retirerProduit(id);
        return;
      }
    }

    this.sauvegarder();
    this.actualiserAffichage();
  }

  retirerProduit(id) {
    if (!confirm("Confirmer la suppression du produit ?")) return;
    this.elements = this.elements.filter(p => p.produit.id !== id);
    this.sauvegarder();
    this.actualiserAffichage();
  }

  total() {
    return this.elements.reduce((t, l) => t + l.produit.prix * l.quantite, 0);
  }

  actualiserAffichage() {
    const zone = document.getElementById("liste-produits");
    const totalZone = document.getElementById("total");
    zone.innerHTML = "";

    if (this.elements.length === 0) {
      zone.innerHTML = "<p>Panier vide</p>";
      totalZone.textContent = "0 €";
      return;
    }

    this.elements.forEach(ligne => {
      const div = document.createElement("div");
      div.className = "produit";

      div.innerHTML = \`
        <div class="produit-info">
          <strong>\${ligne.produit.nom}</strong> - \${ligne.produit.prix.toFixed(2)} € × \${ligne.quantite}
        </div>
        <div class="boutons">
          <button onclick="monPanier.changerQuantite(\${ligne.produit.id}, 'moins')">➖</button>
          <button onclick="monPanier.changerQuantite(\${ligne.produit.id}, 'plus')">➕</button>
          <button onclick="monPanier.retirerProduit(\${ligne.produit.id})">❌</button>
        </div>
      \`;

      zone.appendChild(div);
    });

    totalZone.textContent = this.total().toFixed(2) + " €";
  }
}
  • La classe ajoute dynamiquement les classes CSS : .produit, .boutons, etc.
  • Les boutons ont chacun un comportement visuel propre

🚀 4. Exemple d’utilisation

📋 Copier le code

const clavier = new Produit(1, "Clavier", 49.99, 3, "Clavier mécanique RGB");
const souris = new Produit(2, "Souris", 29.99, 2, "Souris sans fil");

const monPanier = new Panier();
monPanier.ajouterProduit(clavier);
monPanier.ajouterProduit(souris);
  • Ajoute deux produits au chargement
  • Affichage stylé avec les classes définies précédemment

🧭 Prochaine étape

Dans le prochain chapitre, nous allons faire une **revue finale** de l’application : nettoyage, test complet, et possibilités d’extension.

Souhaites-tu passer au Chapitre 9 du Module 3 : Finalisation et tests de l’application panier ?