Ce que vous allez construire
Un système de notation par étoiles interactif, comme ceux que vous voyez sur Amazon ou Google. L’utilisateur survole les étoiles pour prévisualiser sa note, clique pour la valider, et vous récupérez la valeur en JavaScript. Le tout en HTML, CSS et JS pur — zéro dépendance.
Le HTML : simple et sémantique
<div class="star-rating" id="starRating">
<span class="star" data-value="1">★</span>
<span class="star" data-value="2">★</span>
<span class="star" data-value="3">★</span>
<span class="star" data-value="4">★</span>
<span class="star" data-value="5">★</span>
</div>
<p>Votre note : <span id="ratingValue">0</span>/5</p>
★ est le caractère Unicode de l’étoile pleine (★). L’attribut data-value stocke la valeur de chaque étoile.
Le CSS : étoiles dorées et animations
.star-rating {
display: inline-flex;
gap: 4px;
direction: ltr;
}
.star {
font-size: 2.5rem;
color: #ddd;
cursor: pointer;
transition: color 0.15s ease, transform 0.15s ease;
user-select: none;
}
.star:hover { transform: scale(1.2); }
.star.active {
color: #ffc107;
}
.star.hover {
color: #ffdb4d;
}
Le JavaScript : logique d’interaction
const starsContainer = document.getElementById('starRating');
const stars = starsContainer.querySelectorAll('.star');
const ratingValue = document.getElementById('ratingValue');
let currentRating = 0;
// Colorier les étoiles de 1 à N
function highlightStars(count, className) {
stars.forEach((star, index) => {
if (index < count) {
star.classList.add(className);
} else {
star.classList.remove(className);
}
});
}
// Au survol : prévisualisation
starsContainer.addEventListener('mouseover', (e) => {
if (e.target.classList.contains('star')) {
const value = parseInt(e.target.dataset.value);
highlightStars(value, 'hover');
}
});
// Quand la souris quitte : revenir à la note sélectionnée
starsContainer.addEventListener('mouseout', () => {
stars.forEach(star => star.classList.remove('hover'));
});
// Au clic : valider la note
starsContainer.addEventListener('click', (e) => {
if (e.target.classList.contains('star')) {
currentRating = parseInt(e.target.dataset.value);
highlightStars(currentRating, 'active');
ratingValue.textContent = currentRating;
// Ici vous pouvez envoyer la note au serveur
console.log('Note sélectionnée :', currentRating);
}
});
Comment ça fonctionne
On utilise la délégation d’événements : au lieu d’attacher un écouteur à chaque étoile, on en attache un seul au conteneur parent. L’objet e.target identifie quelle étoile a été cliquée. C’est plus performant et plus maintenable que 5 écouteurs séparés.
Version avancée : demi-étoiles
Pour permettre les notes comme 3.5 ou 4.5, divisez chaque étoile en deux moitiés avec des pseudo-éléments :
.star {
position: relative;
display: inline-block;
font-size: 2.5rem;
color: #ddd;
cursor: pointer;
}
.star.half::before {
content: '★';
position: absolute;
left: 0;
width: 50%;
overflow: hidden;
color: #ffc107;
}
En JavaScript, détectez si le clic est dans la moitié gauche ou droite de l’étoile :
star.addEventListener('click', (e) => {
const rect = star.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const isHalf = clickX < rect.width / 2;
const value = parseInt(star.dataset.value);
currentRating = isHalf ? value - 0.5 : value;
});
Envoyer la note au serveur
async function envoyerNote(productId, rating) {
try {
const response = await fetch('/api/ratings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ productId, rating })
});
if (response.ok) {
const data = await response.json();
console.log('Note enregistrée. Moyenne :', data.average);
}
} catch (error) {
console.error('Erreur lors de l\'envoi :', error);
}
}
Exercice
Améliorez le système de notation :
- Ajoutez un message contextuel qui change selon la note : 1★ = « Terrible », 2★ = « Pas terrible », 3★ = « Correct », 4★ = « Bien », 5★ = « Excellent ! »
- Ajoutez une animation de rebond quand l’utilisateur clique
- Empêchez de voter deux fois (désactivez les étoiles après le premier vote)
- Affichez la moyenne des votes avec une barre de progression pour chaque note (comme sur Amazon)