Afficher 5 étoiles les unes à côté des autres, puis les faire se colorer en fonction de la note que vous souhaitez donner à une création, une vidéo, un article,… C’est parfois prise de tête, sprites CSS et autres systèmes de masque. Je vous propose plus simple !
Nous allons faire ça en HTML et CSS, juste pour le fun, ça vous dit ?
Un bout de HTML
Nous allons simplement créer un groupe de lien dans une div
, mais le principe est assez semblable quelle que soit votre structure.
<div class="rating"><!--
--><a href="#5" title="Donner 5 étoiles">☆</a><!--
--><a href="#4" title="Donner 4 étoiles">☆</a><!--
--><a href="#3" title="Donner 3 étoiles">☆</a><!--
--><a href="#2" title="Donner 2 étoiles">☆</a><!--
--><a href="#1" title="Donner 1 étoile">☆</a>
</div>
Les commentaires sont là pour conserver l’indentation et éviter le white-space
. Je vous renvoie sur cette article à propos de inline-block pour plus d’informations.
On commence par un petit problème : on doit inverser le sens des étoiles (liens), la première permet de donner 5 étoiles (meilleure note), la dernière 1 étoile (moins bonne note), mais vous allez comprendre ensuite pourquoi.
Une portion de CSS
Donnons quelques styles de base à notre système d’étoiles.
.rating a {
color: #aaa;
text-decoration: none;
font-size: 3em;
transition: color .4s;
}
.rating a:hover,
.rating a:focus {
color: orange;
cursor: pointer;
}
transition
c’est pour la petite touche d’animation en CSS3, mais c’est optionnel.
Bien, pour le moment nous avons des liens dans le mauvais sens et les étoiles précédents celle survolée ne sont pas orange.
Changeons ça grâce au sélecteur d’adjacence indirecte.
.rating a:hover ~ a,
.rating a:focus ~ a {
color: orange;
}
Voilà, ça c’est fait, pour la couleur… mais on est un peu à l’envers encore.
Qu’à cela ne tienne, la propriété float
à sa valeur right
a un drôle d’effet sur plusieurs éléments disposés ainsi : elle inverse l’ordre.
.rating a {
float: right;
}
Le code CSS final :
.rating a {
float: right;
color: #aaa;
text-decoration: none;
font-size: 3em;
transition: color .4s;
}
.rating a:hover,
.rating a:focus,
.rating a:hover ~ a,
.rating a:focus ~ a {
color: orange;
cursor: pointer;
}
Bien entendu avec des flottants dans les parages, il vous faudra faire attention aux effets de bord, mais ça marche plutôt bien.
Encore du CSS
Il est possible de faire autrement en changeant ponctuellement le sens de lecture. À la place des flottants, nous allons utiliser la propriété direction
.
Je vous donne le code final directement :
.rating {
direction: rtl;
}
.rating a {
color: #aaa;
text-decoration: none;
font-size: 3em;
transition: color .4s;
}
.rating a:hover,
.rating a:focus,
.rating a:hover ~ a,
.rating a:focus ~ a {
color: orange;
cursor: pointer;
}
Limites
Je ne connais pas les répercutions en terme d’accessibilité de l’inversement de l’ordre des liens dans le DOM par rapport à ce qu’on voit réellement à l’écran. Après tout si on vire la CSS, le seul problème serait de présenter comme premier lien la note la plus haute. Soit… je n’y vois pas de souci, si ce n’est que ce n’est pas très habituel, mais tant que l’utilisateur le sait ça ne devrait pas poser de problème ergonomique…
Autre petite note : j’ai utilisé des liens pour la démo, mais il fonctionne aussi avec des boutons radios et ses labels.
Voir la démonstration Le code sur CodePen.io
Sympa 😉
Par contre t’as oublier de rajouter la pseudo-classe :active en même temps que :focus pour que ca soit compatible Ie7
@Sebastien : exact, merci pour le rappel 🙂
Bonjour et merci pour vos articles
La démo de notation fonctionne bien avec FF par contre avec Chrome, la « mémorisation » ne se fait pas.
@Clemzo : en fait il n’y a pas de mémorisation, c’est du HTML et CSS, la mémorisation se fera côté serveur, avec ou sans AJAX.
Le tutoriel ne fait que présenter une solution d’intégration statique 🙂
Franchement bien joué ! Il faut y penser car c’était vraiment tout simple =_=
Merci bien, cela va m’aider pour la prochaine version de GP =D
Merci pour cette présentation , qui pourra me servir prochainement.J’avoue que je suis novice sur les arcanes du css. Merci
Question conne, mais quelle utilité s’il n’y a pas de mémorisation des votes visuellement et sémantique-ment ? Google le prend en compte ou pas ?
Tutoriel pas super complet :/ surtout qu’il n’y en a pas des masses sur les systèmes de natation :/ J’aurais bien aimer que tu dise comment affiche la moyenne des précédant vote.
L’utilité est de présenter une manière d’afficher un système de vote. C’est écrit au début de l’article 😉
Le but n’est pas d’étudier comment créer un composant en HTML/CSS, AJAX et langage serveur, mais uniquement le côté front du site à travers cette astuce qui permet d’éviter un bon nombre de contraintes.
Que tu sois déçu parce que tu ne trouves pas ce que tu veux dans l’article je peux l’admettre, mais au lieu de remettre en question le contenu de l’article (qui traite volontairement une partie technique uniquement), il faudrait peut-être trouver d’autres ressources, non ? Le Web est assez vaste je pense.
(2s de recherche sur Google : http://www.siteduzero.com/forum-83-657928-p1-systeme-de-notation-php-ajax.html )
Bonne journée.
Je suis entrain de mettre un système de vote en place avec ton système et ça fonctionne du tonnerre 🙂
J’ai une petite question : Comment faire pour mettre une note par défaut ? Par exemple, la note moyenne est de 3 étoiles.
Hello mec 🙂
Merci pour ton retour.
Je ne sais pas comment ton code fonctionne niveau serveur/script JS, mais je pense que l’idéal c’est de partir d’une base d’un ensemble
label > input:radio
Puis dans ta CSS tu remplaces les
a
parlabel
et les tu ajoutes dans le sélecteur :Forcément avec la classe ajoutée, ça va te demander un petit coup de JS pour changer sa place en fonction du choix de l’utilisateur 🙂
Idem il faudra cacher les input d’une manière ou d’une autre (peut-être seulement si JS est activé ;p).
L’attribut tabindex de permet de rendre « focusable » les label (au lieu des input:radio).
J’espère que ça marchera, j’ai pas testé 😉
Tuto intéressant.
J’ai essayé la version avec les input radio.
Mais j’ai un problème avec le focus du label qui ne fonctionne pas.
J’ai cherché un peu sur Google et je n’ai pas trouvé de solution à ce problème.
Seule réponse que j’ai pu trouver étant qu’on ne pouvait mettre le focus sur le label 🙁
Bonjour,
Il existe plusieurs solution pour permettre le focus d’un élément ou dans ce cas visualiser un effet sur le label lors du focus de l’input.
Voici l’une d’elle (il s’agit de la première ligne d’étoile) :
http://codepen.io/CreativeJuiz/pen/jEkBL
Bonne journée.
Bonjour,
Parfait ^^
En effet ça fonctionne correctement maintenant 🙂
J’avais testé la solution du « .rating input:focus ~ label, » mais ça ne changeait rien car il faut dire que c’était un problème de label dans mon cas.
J’avais repris le principe de ton code présenté précédemment et encadré les input par les balises de label ce qui posait problème.
Il faut que le label soit placé après l’input pour que ça marche correctement.
Sinon, j’ai remarqué que si on passe sur un autre input on perd l’affichage du focus (logique) lol
J’y ai pallié en rajoutant dans le css la ligne : .rating input:checked ~ label,
En tout cas merci pour ton retour.
Il n’y a pas beaucoup de tuto sur la notation en css (la majorité sont en javascript).
Et ton site est très intéressant et instructif 🙂
Bonne journée.
Très bonne remarque pour le checked, j’ai au la même réflexion car quand on utilise plusieurs fois dans la même page les inputs, lorsqu’on en change un, les autres se réinitialise.
Ligne à rajouter avec hover et focus : .rating input:checked ~ label,
Merci pour ce très bon petit script :).
juste un petite question:
fau t-il faut un codage utf-8?
si oui j’utiliserait un background 😉
Hello,
Je n’ai pas testé, mais tu peux changer le charset du document facilement 😉
Bonne soirée.
Tu n’as pas mis de système de notation pour ton article ? :p
Très simple et complet en tout cas, j’aurais mis 5 🙂
++
Hello,
Ah ah =D Non il n’existe pas encore de système de notation. J’ai peur que ce soit trop superflux commme indicateur :p
Mais merci beaucoup 🙂
Bonjour et merci pour votre article qui me dépasse malheureusement en tant que non développeur ! 😉
N’arrivant pas à trouver ça sur le net, je vous pose la question : comment intégrer ces étoiles de notation dans un mail ?
On peut intégrer la div en html, mais pas possible d’associer le css il me semble. Du coup, ça donne simplement des étoiles sans effet de survol
Bonjour,
En effet dans un mail les effets de survol ne sont pas évidents à produire.
Ce que je vous suggère c’est de la jouer amélioration progressive : juste des étoiles pour les clients mail qui ne supportent pas autre chose que les styles « en ligne », et des effets au survol pour ceux qui ne suppriment pas les styles en en-tête.
Pour plus d’infos sur les supports : https://www.campaignmonitor.com/css/
Bon courage.
Bonjour,
S’il y a encore des gens qui cherchent à savoir comment faire la mémorisation (visuellement) uniquement en HTML/CSS, il suffit de rajouter ces lignes dans le CSS:
.rating input:checked ~ label
{
color: orange;
}
ATTENTION: Ceci fonctionne avec les inputs radio.
Hello,
Attention cependant ça n’enregistre l’information nulle part.
Ce n’est qu’une coche de radio (fonctionne avec checkbox aussi mais je déconseille), donc il faut préparer un script de traitement de formulaire également à côté.
🙂
J’ai grave aimé votre code mais est ce possible d’intégrer ça en PHP , MySQL ? J’ai une table salon et dans la table nous avons id, nom_salon, étoile.
D’où si je rempli la table salon : id: 1, nom_salon: Salon 1, étoile: 3
Maintenant je veux afficher une card dans le HTML, le nom du salon et l’étoile qui sera affiché en étoile comme dans votre code
Merci pour ce très intéressant tuto.
Je développe sous symfony/twig un intranet accessible avec Firefox uniquement et cela fonctionne très bien.
J’ai juste changé le caractère (★ au lieu de ☆) car je trouve que les couleurs sont plus visibles sur le caractère entier et non uniquement le contour.
J’ai remplacé la couleur orange par la couleur de notre site intranet
J’utilise un champ masqué (type= »hidden ») qui va aller récupérer la note choisie.
★★★★★
J’intercepte en jQuery le clic sur une des étoiles pour récupérer le dernier caractère de href (la valeur de la note) et de mettre la note dans l’input id= »projet_note » avant de faire le submit.
$(« .rating a »).click(function(){
var href = $(this).attr(« href »);
var note = href.substr(-1); // le dernier caractère de la valeur de href = la note
$(« #projet_note »).val(note);
});
Merci pour le partage Philippe 🙂