5 votes

Problème des étoiles de classement CSS avec les touches fléchées

J'ai un problème avec mon système d'étoiles d'évaluation qui utilise du CSS pur. Le problème est que lorsque j'utilise les touches fléchées pour sélectionner les étoiles... c'est à l'envers. Je dois utiliser la touche fléchée gauche pour aller à droite ou la touche fléchée droite pour aller à gauche. J'ai essayé de jouer avec les flottants, mais cela n'a rien donné. J'ai également essayé de réorganiser le balisage mais j'ai obtenu des résultats similaires.

.rating {
  float: left;
}

.rating:not(:checked)>input {
  position: absolute;
  top: -9999px;
  clip: rect(0, 0, 0, 0);
}

.rating:not(:checked)>label {
  float: right;
  width: 1em;
  padding: 0 .1em;
  overflow: hidden;
  white-space: nowrap;
  cursor: pointer;
  font-size: 200%;
  line-height: 1.2;
  color: #ddd;
  text-shadow: 1px 1px #bbb, 2px 2px #666, .1em .1em .2em rgba(0, 0, 0, .5);
}

.rating:not(:checked)>label:before {
  content: '★ ';
}

.rating>input:checked~label {
  color: #f70;
  text-shadow: 1px 1px #c60, 2px 2px #940, .1em .1em .2em rgba(0, 0, 0, .5);
}

.rating:not(:checked)>label:hover,
.rating:not(:checked)>label:hover~label {
  color: gold;
  text-shadow: 1px 1px goldenrod, 2px 2px #B57340, .1em .1em .2em rgba(0, 0, 0, .5);
}

.rating>input:checked+label:hover,
.rating>input:checked+label:hover~label,
.rating>input:checked~label:hover,
.rating>input:checked~label:hover~label,
.rating>label:hover~input:checked~label {
  color: #ea0;
  text-shadow: 1px 1px goldenrod, 2px 2px #B57340, .1em .1em .2em rgba(0, 0, 0, .5);
}

.rating>label:active {
  position: relative;
  top: 2px;
  left: 2px;
}

<fieldset class="rating">
  <legend>Please rate:</legend>
  <input type="radio" id="star5" name="rating" value="5" /><label for="star5" title="Rocks!">5 stars</label>
  <input type="radio" id="star4" name="rating" value="4" /><label for="star4" title="Pretty good">4 stars</label>
  <input type="radio" id="star3" name="rating" value="3" /><label for="star3" title="Meh">3 stars</label>
  <input type="radio" id="star2" name="rating" value="2" /><label for="star2" title="Kinda bad">2 stars</label>
  <input type="radio" id="star1" name="rating" value="1" /><label for="star1" title="Sucks big time">1 star</label>
</fieldset>

Démonstration de JSFiddle

1voto

Nuvanda Points 337

Comme @randomguy04 l'a déjà signalé, l'inversion est due au fait que les boutons radio sont inversés dans le DOM. Comme il n'y a aucun moyen d'attribuer un ordre aux boutons en HTML, vous devrez modifier votre balisage pour qu'il contienne la balise <input> dans le bon ordre, pour un exemple comme celui-ci :

<fieldset class="rating">
    <legend>Please rate:</legend>
    <input type="radio" id="star1" name="rating" value="1">
    <input type="radio" id="star2" name="rating" value="2">
    <input type="radio" id="star3" name="rating" value="3">
    <input type="radio" id="star4" name="rating" value="4">
    <input type="radio" id="star5" name="rating" value="5">
    <label for="star5" title="Rocks!">5 stars</label>
    <label for="star4" title="Pretty good">4 stars</label>
    <label for="star3" title="Meh">3 stars</label>
    <label for="star2" title="Kinda bad">2 stars</label>
    <label for="star1" title="Sucks big time">1 star</label>
</fieldset>

Le CSS nécessaire pour que cela fonctionne est un peu laid, car il n'y a pas de sélecteurs pour les parents et les frères et sœurs précédents, ce qui rend le rendu plus facile à optimiser. Quelque chose comme ceci pourrait fonctionner :

.rating {
    float:left;
}

/*
 * :not(:checked) is a filter, so that browsers that don’t support :checked 
 * don’t follow these rules. Every browser that supports :checked also supports 
 * :not(), so it doesn’t make the test unnecessarily selective
 */
.rating:not(:checked) > input {
    position:absolute;
    top:-9999px;
    clip:rect(0,0,0,0);
}

.rating:not(:checked) > label {
    float:right;
    width:1em;
    padding:0 .1em;
    overflow:hidden;
    white-space:nowrap;
    cursor:pointer;
    font-size:200%;
    line-height:1.2;
    color:#ddd;
    text-shadow: 1px 1px #bbb, 2px 2px #666, .1em .1em .2em rgba(0,0,0,.5);
}

.rating:not(:checked) > label:before {
    content: '★ ';
}

.rating > input#star1:checked ~ label[for="star1"],
.rating > input#star1:checked ~ label[for="star1"] ~ label,
.rating > input#star2:checked ~ label[for="star2"],
.rating > input#star2:checked ~ label[for="star2"] ~ label,
.rating > input#star3:checked ~ label[for="star3"],
.rating > input#star3:checked ~ label[for="star3"] ~ label,
.rating > input#star4:checked ~ label[for="star4"],
.rating > input#star4:checked ~ label[for="star4"] ~ label,
.rating > input#star5:checked ~ label[for="star5"],
.rating > input#star5:checked ~ label[for="star5"] ~ label {
    color: #f70;
    text-shadow: 1px 1px #c60, 2px 2px #940, .1em .1em .2em rgba(0,0,0,.5);
}

.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
    color: gold;
    text-shadow: 1px 1px goldenrod, 2px 2px #B74, .1em .1em .2em rgba(0,0,0,.5);
}

.rating > input#star1:checked ~ label[for="star1"]:hover,
.rating > input#star1:checked ~ label[for="star1"] ~ label:hover,
.rating > input#star2:checked ~ label[for="star2"]:hover,
.rating > input#star2:checked ~ label[for="star2"] ~ label:hover,
.rating > input#star3:checked ~ label[for="star3"]:hover,
.rating > input#star3:checked ~ label[for="star3"] ~ label:hover,
.rating > input#star4:checked ~ label[for="star4"]:hover,
.rating > input#star4:checked ~ label[for="star4"] ~ label:hover,
.rating > input#star5:checked ~ label[for="star5"]:hover,
.rating > input#star5:checked ~ label[for="star5"] ~ label:hover,
.rating > input#star1:checked ~ label[for="star1"]:hover ~ label,
.rating > input#star1:checked ~ label[for="star1"] ~ label:hover ~ label,
.rating > input#star2:checked ~ label[for="star2"]:hover ~ label,
.rating > input#star2:checked ~ label[for="star2"] ~ label:hover ~ label,
.rating > input#star3:checked ~ label[for="star3"]:hover ~ label,
.rating > input#star3:checked ~ label[for="star3"] ~ label:hover ~ label,
.rating > input#star4:checked ~ label[for="star4"]:hover ~ label,
.rating > input#star4:checked ~ label[for="star4"] ~ label:hover ~ label,
.rating > input#star5:checked ~ label[for="star5"]:hover ~ label,
.rating > input#star5:checked ~ label[for="star5"] ~ label:hover ~ label,
.rating > input#star1:checked ~ label:hover ~ label[for="star1"],
.rating > input#star1:checked ~ label:hover ~ label[for="star1"] ~ label,
.rating > input#star2:checked ~ label:hover ~ label[for="star2"],
.rating > input#star2:checked ~ label:hover ~ label[for="star2"] ~ label,
.rating > input#star3:checked ~ label:hover ~ label[for="star3"],
.rating > input#star3:checked ~ label:hover ~ label[for="star3"] ~ label,
.rating > input#star4:checked ~ label:hover ~ label[for="star4"],
.rating > input#star4:checked ~ label:hover ~ label[for="star4"] ~ label,
.rating > input#star5:checked ~ label:hover ~ label[for="star5"],
.rating > input#star5:checked ~ label:hover ~ label[for="star5"] ~ label {
    color: #ea0;
    text-shadow:1px 1px goldenrod, 2px 2px #B74, .1em .1em .2em rgba(0,0,0,.5);
}

Notez que dans les boutons radio, la flèche vers le haut sélectionne le bouton précédent, tandis que la flèche vers le bas sélectionne le bouton suivant. Ce comportement, qui est très naturel avec les boutons radio ordinaires, peut sembler contre-indiqué avec vos étoiles de classement. Je crains cependant que, en utilisant uniquement CSS, il n'y ait aucun moyen de commuter uniquement les flèches gauche et droite sans commuter également les flèches haut et bas.

Violon

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X