Search code examples
htmlcssinputlabel

Star rating "Turned Around" - HTML, CSS


I want to make a star rating by hiding the input (radio buttons) and just displaying the label (which is star shaped). By clicking on one of the stars, all stars before it should become yellow too. So I wrote the following:

HTML and CSS creating radio buttons and labels:

input:not(:checked)~label:hover,
label:hover~input:not(checked)~label {
  color: #fd4;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<input type="radio" name="rate" id="rate-1">
<label for="rate-1" class="fa-solid fa-star"></label>
<input type="radio" name="rate" id="rate-2">
<label for="rate-2" class="fa-solid fa-star"></label>
<input type="radio" name="rate" id="rate-3">
<label for="rate-3" class="fa-solid fa-star"></label>
<input type="radio" name="rate" id="rate-4">
<label for="rate-4" class="fa-solid fa-star"></label>
<input type="radio" name="rate" id="rate-5">
<label for="rate-5" class="fa-solid fa-star"></label>

But the stars are highlighted from right to left, so if you for example hover over 4 stars, the forth and fifth star is highlighted.

picture of example

How can I fix this?


Solution

  • A simple solution would be to add a container with display:flex; and use flex-direction to reverse the elements. Because the elements are displayed in the DOM reversed, you will need to be sure to reverse the order of the elements in the HTML as well, so that you are still getting the correct rating.

    input:not(:checked)~label:hover,
    label:hover~input:not(checked)~label {
      color: #fd4;
    }
    .rating-container {
      display:flex;
      flex-direction:row-reverse;
      justify-content:center;
    }
    input[type="radio"] {
      display:none;
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />
    <div class="rating-container">
      <input type="radio" name="rate" id="rate-5">
      <label for="rate-5" class="fa-solid fa-star"></label>
      <input type="radio" name="rate" id="rate-4">
      <label for="rate-4" class="fa-solid fa-star"></label>
      <input type="radio" name="rate" id="rate-3">
      <label for="rate-3" class="fa-solid fa-star"></label>
      <input type="radio" name="rate" id="rate-2">
      <label for="rate-2" class="fa-solid fa-star"></label>
      <input type="radio" name="rate" id="rate-1">
      <label for="rate-1" class="fa-solid fa-star"></label>
    </div>