Search code examples
htmlcssclasssystemvote

How to make hovering over a class to trigger changes in other classes?


I want to make a pure css [no jquery] star rating system. So I have a html form with 5 radio buttons. So far I can make when I hover/click on a star radio button to change it's own background image. It works for every star BUT separately. When I click on the fifth star - only the fifth star is changed. When I click on the fourth star - only the fourth star is changed and so on. I want to make that when I hover/click on the fifth star -> all stars to change their background image. When I click on the second star the first two stars to change and etc. so the user can see for how much stars he is voting. (you've seen these rating systems all over the internet)

I want to make like these (again only css):

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

But I end up with this:

enter image description here

So I have 5 stars/radio inputs and each is from a class:

1 star -> radioStarButton1

2 star -> radioStarButton2

3 star -> radioStarButton3

4 star -> radioStarButton4

5 star -> radioStarButton5

           <input type="radio" name="stars" id="'.'2stars-for-id-'.$row['id'].'" class="radioStarButton2" value="2" />
           <label for="'.'2stars-for-id-'.$row['id'].'"></label>

           <input type="radio" name="stars" id="'.'3stars-for-id-'.$row['id'].'" class="radioStarButton3" value="3" checked />
           <label for="'.'3stars-for-id-'.$row['id'].'"></label>

           <input type="radio" name="stars" id="'.'4stars-for-id-'.$row['id'].'" class="radioStarButton4" value="4" />
           <label for="'.'4stars-for-id-'.$row['id'].'"></label>

           <input type="radio" name="stars" id="'.'5stars-for-id-'.$row['id'].'" class="radioStarButton5" value="5" />
           <label for="'.'5stars-for-id-'.$row['id'].'"></label>

I want to make when I hover/click on the second class .radioStarButton2 to change also the fist class -> .radioStarButton1 and THAT is the problem - to change more than one class elements IF it is possible.

Also the css: This is working css:

input[type="radio"]{
display:none;
}

input[type="radio"] + label
{
    background-image: url("uncheckedstar.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}

.radioStarButton1:hover + label
{
    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}
.radioStarButton1:checked + label
{
    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}

The next code is obviously wrong but I don't know how to do it. I'm uploading it only for an idea what I'm trying to do:

.radioStarButton2:hover + label , .radioStarButton1
{

    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}
.radioStarButton2:checked + label , .radioStarButton1
{
    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}

.radioStarButton3:hover + label , .radioStarButton1 , .radioStarButton2
{

    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}
.radioStarButton3:checked + label , .radioStarButton1 , .radioStarButton2
{
    background-image: url("star.png");
    height: 23px;
    width: 23px;
    display:inline-block;
    padding: 0 0 0 0px;
}

Solution

  • An extension of Koen's solution ... and stays after clicked as well ... you need to re-position/style the labels (and add your stars), hide the inputs, but it's CSS only

    Demo: http://jsfiddle.net/f82Fg/2/

    HTML

    <div class="butts">
        <input id="r5" type="radio" class="butt" value="5" />
        <label for="r5">5</label>
        <input id="r4" type="radio" class="butt" value="4" />
        <label for="r4">4</label>
        <input id="r3" type="radio" class="butt" value="3" />
        <label for="r3">3</label>
        <input id="r2" type="radio" class="butt" value="2" />
        <label for="r2">2</label>
        <input id="r1" type="radio" class="butt" value="1" />
        <label for="r1">1</label>
    </div>
    

    CSS

    .butts {
        float: left;
    }
    .butt {
        display: block;
        float: right;    
        width: 16px;
        height: 16px;
    }
    .butt:hover,
    .butt:hover ~ .butt,
    .butt:hover ~ label {
        background-color: blue;
    }
    .butt:checked,
    .butt:checked ~ .butt,
    .butt:checked ~ label {
        background-color: red;
    }