I use this code to display stars:
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>
Dynamic code:
<ul class="rating">
<?php foreach ($this->getRatings() as $_rating): ?>
<li>
<span class="rowlabel"><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span>
<span class="ratingSelector">
<?php foreach ($_rating->getOptions() as $_option): ?>
<input type="radio" name="ratings[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5" value="<?php echo $_option->getId() ?>" class="radio" /><label class="full" for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5"></label>
<?php endforeach; ?>
</span>
</li>
<?php endforeach; ?>
</ul>
But hovering and selecting currently works from right to left, but I want to change this from left to right.
Code is loaded dynamically, so I can not change the sort and put value 5 first. This dynamic code is loaded 5 times, for 5 different ratings.
How can I change this? Or what code of JQuery do I need?
JSFiddle: /
I use this code to display stars:
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>
Dynamic code:
<ul class="rating">
<?php foreach ($this->getRatings() as $_rating): ?>
<li>
<span class="rowlabel"><?php echo $this->escapeHtml($_rating->getRatingCode()) ?></span>
<span class="ratingSelector">
<?php foreach ($_rating->getOptions() as $_option): ?>
<input type="radio" name="ratings[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5" value="<?php echo $_option->getId() ?>" class="radio" /><label class="full" for="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>-<?php echo $_option->getValue() ?>-5"></label>
<?php endforeach; ?>
</span>
</li>
<?php endforeach; ?>
</ul>
But hovering and selecting currently works from right to left, but I want to change this from left to right.
Code is loaded dynamically, so I can not change the sort and put value 5 first. This dynamic code is loaded 5 times, for 5 different ratings.
How can I change this? Or what code of JQuery do I need?
JSFiddle: https://jsfiddle/9nn14beq/
Share Improve this question edited Jun 1, 2015 at 11:02 JGeer asked Jun 1, 2015 at 8:27 JGeerJGeer 1,8521 gold badge36 silver badges78 bronze badges 8- I don't think this is possible with only css. because css rule is applied for next sibling not for previous. You should also use JQuery. – ketan Commented Jun 1, 2015 at 8:34
- 1 See my star rating system in CSS - codepen.io/vsync/pen/qvhtf – vsync Commented Jun 1, 2015 at 8:37
- @vsync What exactly are you doing different than my code? – JGeer Commented Jun 1, 2015 at 8:42
- @Jelle - well I saw you are trying to make a star rating system and since I wrote a good one some years ago, I thought it would be nice to share it, so you could use it. Read the source code and learn how it was done – vsync Commented Jun 1, 2015 at 9:19
- @ketan Yes, it is posible with CSS only. See my answer – vals Commented Jun 1, 2015 at 9:56
4 Answers
Reset to default 8This can almost work with pure CSS. It does need one line of JavaScript to set the initial value though:
document.getElementById('Degelijkheid-1-5').checked = true;
.rating input {
display: none;
}
.rating label:before {
margin: 5px;
font-size: 1.25em;
font-family: FontAwesome;
display: inline-block;
content:"\f005";
}
li {
list-style:none;
}
.ratingSelector input + label {
color: #FFD700;
}
.ratingSelector input:checked ~ input:not(:checked) ~ label {
color: #ddd;
}
.ratingSelector input:checked ~ input:not(:checked) + label:hover ~ label {
color: #ddd;
}
.ratingSelector:hover input + label,
.ratingSelector:hover input:checked + label {
color: #FFED85;
}
.ratingSelector:hover input:checked ~ input:not(:checked) ~ label:hover,
.ratingSelector:hover input:checked ~ input:not(:checked) + label {
color: #FFD700;
}
.ratingSelector:hover input:checked ~ input:not(:checked) ~ label:hover ~ label {
color: #ddd !important;
}
.ratingSelector input + label:hover ~ label {
color: #ddd !important;
}
<ul class="rating">
<li> <span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio"/>
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio"/>
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio"/>
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio"/>
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio"/>
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>
EDIT
To use JS (to re-order the items):
var objGroup = document.getElementsByClassName('ratingSelector');
for (var i = 0; i < objGroup.length; i++) {
var objRadio = [].slice.call(objGroup[i].getElementsByClassName('full')); // Create an array of items
for (var j = objRadio.length; j--;) { // Loop through the array backwards
var checkbox = document.getElementById(objRadio[j].getAttribute('for'));
objGroup[i].appendChild(checkbox);
objGroup[i].appendChild(objRadio[j]);
}
}
.rating {
direction: rtl;
text-align: left;
}
.rating input {
display: none;
}
.rating label:before {
margin: 5px;
font-size: 1.25em;
font-family: FontAwesome;
display: inline-block;
content: "\f005";
}
li {
list-style: none;
}
.rating label {
color: #ddd;
}
/***** CSS to Highlight Stars on Hover *****/
.ratingSelector input:checked ~ label,
/* show gold star when clicked */
.ratingSelector label:hover,
/* hover current star */
.ratingSelector label:hover ~ label {
color: #FFD700;
}
/* hover previous stars in list */
.ratingSelector input:checked + label:hover,
/* hover current star when changing rating */
.ratingSelector input:checked ~ label:hover,
.ratingSelector label:hover ~ input:checked ~ label,
/* lighten current selection */
.ratingSelector input:checked ~ label:hover ~ label {
color: #FFED85;
}
<ul class="rating">
<li> <span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio"/>
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio"/>
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio"/>
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio"/>
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio"/>
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
<li> <span class="ratingSelector">
<input type="radio" name="ratings[2]" id="Design-1-5" value="1" class="radio"/>
<label class="full" for="Design-1-5"></label>
<input type="radio" name="ratings[2]" id="Design-2-5" value="2" class="radio"/>
<label class="full" for="Design-2-5"></label>
<input type="radio" name="ratings[2]" id="Design-3-5" value="3" class="radio"/>
<label class="full" for="Design-3-5"></label>
<input type="radio" name="ratings[2]" id="Design-4-5" value="4" class="radio"/>
<label class="full" for="Design-4-5"></label>
<input type="radio" name="ratings[2]" id="Design-5-5" value="5" class="radio"/>
<label class="full" for="Design-5-5"></label>
</span>
</li>
<li> <span class="ratingSelector">
<input type="radio" name="ratings[3]" id="Gebruiksgemak-1-5" value="1" class="radio"/>
<label class="full" for="Gebruiksgemak-1-5"></label>
<input type="radio" name="ratings[3]" id="Gebruiksgemak-2-5" value="2" class="radio"/>
<label class="full" for="Gebruiksgemak-2-5"></label>
<input type="radio" name="ratings[3]" id="Gebruiksgemak-3-5" value="3" class="radio"/>
<label class="full" for="Gebruiksgemak-3-5"></label>
<input type="radio" name="ratings[3]" id="Gebruiksgemak-4-5" value="4" class="radio"/>
<label class="full" for="Gebruiksgemak-4-5"></label>
<input type="radio" name="ratings[3]" id="Gebruiksgemak-5-5" value="5" class="radio"/>
<label class="full" for="Gebruiksgemak-5-5"></label>
</span>
</li>
</ul>
You expected thing is possible with only css. Because css rule is applied for next sibling not for previous. You should also use JQuery.
But you can do it using following trick using css:
.rating input { display: none; }
.rating label:before {
margin: 5px;
font-size: 1.25em;
font-family: FontAwesome;
display: inline-block;
content: "\f005";
}
li {list-style:none;
direction:rtl;
text-align: left;}
.rating label {
color: #ddd;
}
/***** CSS to Highlight Stars on Hover *****/
.rating input:checked ~ label, /* show gold star when clicked */
.rating:not(:checked) label:hover, /* hover current star */
.rating:not(:checked) label:hover ~ label { color: #FFD700; } /* hover previous stars in list */
.rating input:checked + label:hover, /* hover current star when changing rating */
.rating input:checked ~ label:hover,
.rating label:hover ~ input:checked ~ label, /* lighten current selection */
.rating input:checked ~ label:hover ~ label { color: #FFED85; }
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
</span>
</li>
</ul>
As stated in previous answers, CSS selectors work only in the netural order of the DOM. (Even though this can change some time in the future).
So, if you can not change your DOM, you need to reverse your CSS logic:
Change all the elements on hover of the container. And then use the sibling selector to change the elements to the right of the hovered item
.rating input { display: none; }
.rating label:before {
margin: 5px;
font-size: 1.25em;
font-family: FontAwesome;
display: inline-block;
content: "\f005";
}
li {list-style:none; }
/***** CSS to Highlight Stars on Hover *****/
.rating label {color: grey;}
label:hover { color: red; }
.ratingSelector:hover .full {color: red; }
.full:hover ~ .full { color: grey !important; }
<ul class="rating">
<li>
<span class="ratingSelector">
<input type="radio" name="ratings[1]" id="Degelijkheid-1-5" value="1" class="radio">
<label class="full" for="Degelijkheid-1-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-2-5" value="2" class="radio">
<label class="full" for="Degelijkheid-2-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-3-5" value="3" class="radio">
<label class="full" for="Degelijkheid-3-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-4-5" value="4" class="radio">
<label class="full" for="Degelijkheid-4-5"></label>
<input type="radio" name="ratings[1]" id="Degelijkheid-5-5" value="5" class="radio">
<label class="full" for="Degelijkheid-5-5"></label>
</span>
</li>
</ul>
Just add the below CSS code to make it from left to right:
.ratingSelector {
max-width: 145px;
display: inline-block;
}
.rating label {
float: right;
}