CSS Star Ratings with Radio Buttons

Viewed 46

I am trying to change a radio button form to a Star Rating System. (https://jsfiddle.net/dtau58g6/) . Unfortunately, the html is generated by WordPress so I can only edit the CSS. My problem is that the hover and checked do not work as expected.

  • What I want is when the second star is selected then, the first one is full as well.
  • Also, when we hover over the third star, the first and second stars are full as well.
  • If the third item is selected, and we hover over the second star, then only the first and the second stars are full. But when we remove our mouse the the third star becomes full again as it was already selected.

.form-group {
  display: flex;
}

.form-check-inline .rating {
  display: none;
}

.form-check-inline span {
  padding-right: 2%;
  cursor: pointer;
  color: transparent;
}

.form-check-inline span:before {
  content: '\2606';
  color: gold;
}

.form-check-inline span:hover:before,
.form-check-inline span:hover ~ span:before {
  content: '\2605';
  color: gold;
}

.form-check-inline .rating:checked ~ span:before {
  content: '\2605';
  color: gold;
}
  <div class="form-group">
    <div class="form-check-inline">
      <label class="form-check-label" for="1">
        <input type="radio" id="1" value="1" name="rating" class="rating" />
        <span class="wpcomment-input-option-label wpcomment-label-radio">1</span>
      </label>
    </div>

    <div class="form-check-inline">
      <label class="form-check-label" for="2">
        <input type="radio" id="2" value="2" name="rating" class="rating" checked="checked"/>
        <span class="wpcomment-input-option-label wpcomment-label-radio">2</span>
      </label>
    </div>

    <div class="form-check-inline">
      <label class="form-check-label" for="3">
        <input type="radio" id="3" value="3" name="rating" class="rating" />
        <span class="wpcomment-input-option-label wpcomment-label-radio">3</span>
      </label>
    </div>
  </div>

1 Answers

The answer is 'yes you can' but with a caveat that this uses the :has() pseudo class which isn't implemented in all browsers (e.g. firefox) yet.

It's possible to tidy these rules up a bit using :where() too.

See below

.form-group {
  display: flex;
}

.form-check-inline .rating {
  display: none;
}

.form-check-inline span {
  padding-right: 2%;
  cursor: pointer;
  color: transparent;
}

.form-check-inline span:before {
  content: '\2606';
  color: gold;
}

.form-check-inline span:hover:before,
.form-check-inline span:hover~span:before {
  content: '\2605';
  color: gold;
}

.form-check-inline .rating:checked~span:before {
  content: '\2605';
  color: gold;
}

.form-group:has(input[id="2"]:checked) input[id='1']+span:before {
  content: '\2605';
  color: gold;
}

.form-group:has(input[id="3"]:checked) input[id='1']+span:before,
.form-group:has(input[id="3"]:checked) input[id='2']+span:before {
  content: '\2605';
  color: gold;
}

.form-group:has(input[id="2"]:hover) input[id='1']+span:before {
  content: '\2605';
  color: gold;
}

.form-group:has(input[id="3"]:hover) input[id='1']+span:before,
.form-group:has(input[id="3"]:hover) input[id='2']+span:before {
  content: '\2605';
  color: gold;
}
<div class="form-group">
  <div class="form-check-inline">
    <label class="form-check-label" for="1">
        <input type="radio" id="1" value="1" name="rating" class="rating" />
        <span class="wpcomment-input-option-label wpcomment-label-radio">1</span>
      </label>
  </div>

  <div class="form-check-inline">
    <label class="form-check-label" for="2">
        <input type="radio" id="2" value="2" name="rating" class="rating" checked="checked" />
        <span class="wpcomment-input-option-label wpcomment-label-radio">2</span>
      </label>
  </div>

  <div class="form-check-inline">
    <label class="form-check-label" for="3">
        <input type="radio" id="3" value="3" name="rating" class="rating" />
        <span class="wpcomment-input-option-label wpcomment-label-radio">3</span>
      </label>
  </div>
</div>

Related