Stars rating ranking with arrows.

I have a problem with my star rating system that uses pure CSS. My problem is that when I use the arrow keys to select stars ... this is the opposite. I have to use the left arrow key to go to the right or right arrow key to go left. I tried to play with floats, but that didn't help. I also tried rearranging the markup, but I had similar results.

.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> 

JSFiddle Demo

+5
source share
1 answer

As @ randomguy04 explained, the reversal is due to the fact that the radio buttons switch in the DOM. Since there is no way to assign Order buttons to HTML, you will have to change your markup to contain <input> in the correct order, for example Example:

 <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> 

The CSS needed to do this job gets a little ugly, as CSS does not have selectors for parents and previous siblings to make rendering optimization easier. Something like this will work:

 .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); } 

Notice that in the switches, the up arrow selects the previous button, and the down arrow selects the next button. This behavior, which is very natural when using conventional switches, may seem intuitive to your rating stars. I am afraid, however, that using only CSS, there is no way to switch only the left and right arrow keys without switching up and down.

Fiddle

+1
source

Source: https://habr.com/ru/post/1270692/


All Articles