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 ?

Voir la démonstration

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