Star Rating System in RTL

Viewed 359

I have a star rating system that build with HTML and CSS only, in left to right it's Work fine, but in Right to left it's still in Left to right, I want the first star from right filled first and the last one (5) filled recent How can I make the star direction from right to left filled.

.rate {
  display: flex;
  height: 46px;
  padding: 0 10px;
}

.rate:not(:checked)>input {
  position: absolute;
  top: -9999px;
  visibility: hidden;
}

.rate:not(:checked)>label {
  float: right;
  width: 1em;
  overflow: hidden;
  white-space: nowrap;
  cursor: pointer;
  font-size: 30px;
  color: #ccc;
}

.rate:not(:checked)>label:before {
  content: '★ ';
}

.rate>input:checked~label {
  color: #ffc700;
}

.rate:not(:checked)>label:hover,
.rate:not(:checked)>label:hover~label {
  color: #deb217;
}
<div class="rate" onclick="validate()">
  <input type="radio" id="star5" class="star" name="rate" value="5" />
  <label for="star5">5 stars</label>
  <input type="radio" id="star4" class="star" name="rate" value="4" />
  <label for="star4">4 stars</label>
  <input type="radio" id="star3" class="star" name="rate" value="3" />
  <label for="star3">3 stars</label>
  <input type="radio" id="star2" class="star" name="rate" value="2" />
  <label for="star2">2 stars</label>
  <input type="radio" id="star1" class="star" name="rate" value="1" />
  <label for="star1">1 star</label>

3 Answers

not too sure if your code worked , somehow it seemed to me to work the opposite way hilighting the whole row of stars at first.

You can imbricate flex box, it will inherit the direction flow and if you also wrap the stars in a container , you can reverse it's own flow too to reverse the visual stars notation .

example :

.rate {
  display: flex;
  height: 46px;
  padding: 0 10px;
}
.rate span {
  display: inline-flex;
  flex-flow: row-reverse;

  margin:auto 1em;
}
.rtl {
  direction: rtl;
}
.rate:not(:checked) > span input {
  position: absolute;
  right: 100vw;
}

.rate:not(:checked) > span label {
  width: 1em;
  overflow: hidden;
  white-space: nowrap;
  cursor: pointer;
  font-size: 30px;
  color: #ccc;
}

.rate:not(:checked) > span label:before {
  content: "★ ";
}

.rate > span input:checked ~ label {
  color: #ffc700;
}

.rate:not(:checked) > span label:hover,
.rate:not(:checked) > span label:hover ~ label {
  color: #deb217;
}
<div dir ="rtl" class="rate" onclick="validate()">
  <span>
    <input type="radio" id="star5" data-product-id="@Model.ProductId" class="star" name="rate" value="5" />
    <label for="star5"  title="5 Stars">5 stars</label>
    <input type="radio" id="star4" data-product-id="@Model.ProductId" class="star" name="rate" value="" />
    <label for="star4"  title="4 Star">4 stars</label>
    <input type="radio" id="star3" data-product-id="@Model.ProductId" class="star" name="rate" value="3" />
    <label for="star3" title="3 Star">3 stars</label>
    <input type="radio" id="star2" data-product-id="@Model.ProductId" class="star" name="rate" value="2" />
    <label for="star2" title="2 Stars">2 stars</label>
    <input type="radio" id="star1" data-product-id="@Model.ProductId" class="star" name="rate" value="1" />
    <label for="star1" title="1 Star">1 star</label>  
  </span>
  <p>אני מניח שיש כאן הודעה?</p>
</div>
<hr>
<div class="rate" onclick="validate()">
  <span>
    <input type="radio" id="star5a" data-product-id="@Model.ProductId" class="star" name="rate" value="5" />
    <label for="star5a"  title="5 Stars">5 stars</label>
    <input type="radio" id="star4a" data-product-id="@Model.ProductId" class="star" name="rate" value="" />
    <label for="star4a"  title="4 Star">4 stars</label>
    <input type="radio" id="star3a" data-product-id="@Model.ProductId" class="star" name="rate" value="3" />
    <label for="star3a" title="3 Star">3 stars</label>
    <input type="radio" id="star2a" data-product-id="@Model.ProductId" class="star" name="rate" value="2" />
    <label for="star2a" title="2 Stars">2 stars</label>
    <input type="radio" id="star1a" data-product-id="@Model.ProductId" class="star" name="rate" value="1" />
    <label for="star1a" title="1 Star">1 star</label>  
  </span>
  <p>I guess there is content aside here ?</p>
</div>


A few links than could be usefull aside this answer.


I used flex flow property with row-reverse value. I think this solution may help you to solve your problem. And I used float property with left value to get rate div to left position.

.rate {
  display: flex;
  height: 46px;
  padding: 0 10px;
  flex-flow: row-reverse wrap;
  float: left;
}

.rate:not(:checked)>input {
  position: absolute;
  top: -9999px;
  visibility: hidden;
}

.rate:not(:checked)>label {
  float: right;
  width: 1em;
  overflow: hidden;
  white-space: nowrap;
  cursor: pointer;
  font-size: 30px;
  color: #ccc;
}

.rate:not(:checked)>label:before {
  content: '★ ';
}

.rate>input:checked~label {
  color: #ffc700;
}

.rate:not(:checked)>label:hover,
.rate:not(:checked)>label:hover~label {
  color: #deb217;
}
<div class="rate" onclick="validate()">
  <input type="radio" id="star5" class="star" name="rate" value="5" />
  <label for="star5">5 stars</label>
  <input type="radio" id="star4" class="star" name="rate" value="4" />
  <label for="star4">4 stars</label>
  <input type="radio" id="star3" class="star" name="rate" value="3" />
  <label for="star3">3 stars</label>
  <input type="radio" id="star2" class="star" name="rate" value="2" />
  <label for="star2">2 stars</label>
  <input type="radio" id="star1" class="star" name="rate" value="1" />
  <label for="star1">1 star</label>

Related