How do I dynamically color stars in a star rating?

2019-03-06 19:29发布

I have a form where users can rate a product, where I need to visually show a star rating. I need to colour the stars according to the rating value I'm retrieving from the database, for each user as well as an overall average.

For example, user A has given a 5 star rating, and user B has given 3 stars only. When I display the rating of user A, I have to colour all 5 stars, but when I display the rating of user B, I have to colour only 3 stars. That means I have to dynamically colour the stars.

I have also seen on most sites when displaying average ratings, they have coloured half of the star where the average rating ends in half a star. I would like to do that too.

My display does not need to contain a hover feature.

My question is about how to colour the stars according to the calculated average or the rating pulled from the database.

I'm using codeigniter in my project.

Thank you for any help :-)

1条回答
Melony?
2楼-- · 2019-03-06 20:26

Have one <span> element nested inside another.
The outer <span> has a background image of empty stars.
The inner <span> has a background image of a colored-in star, and a width: element that is programmatically set when you layout the page. For example, width:60.0% could be used for a 3/5 star rating.

For a small optimization, you may even use start with an image that is only one star and use repeat-x to get all 5 stars. You could also have an image that includes both colored and filled-in stars vertically, and crop at display time to determine which version of the star you are referencing.

Example 1:

For example, consider the following CSS:

span.rating-frame, span.rating-fill {
    background: url(../star.png) 0 -16px repeat-x;
    display: block;
    width: 80px; /* this is 5 times the width of the star, for 5 stars total */
    height: 16px;
}
span.rating-fill {
    background-position: 0 0; /* use the (filled-in) version from the top of the image */
}

and the following HTML:

Average Rating: 4/5
<span class="rating-frame">
      <span style="width:80.0%;" class="rating-fill"> </span>
</span>

User A:  5/5
<span class="rating-frame">
      <span style="width:100.0%;" class="rating-fill"> </span>
</span>

User B: 3/5
<span class="rating-frame">
      <span style="width:60.0%;" class="rating-fill"> </span>
</span>

This assumes that star.png is a 16x32 image with the filled-in star on top.
The value for the width attribute is set by userRating/maxPossibleRating rounded to an appropriate precision. Of course, where you show the overall average rating, it's set by averageUserRating/maxPossibleRating.


Example 2:

OP reports using <span>☆</span> instead. The following pseudocode might be helpful in page generation there.

for (i = 1 to rating inclusive) {
    print "<span>★</span>"
}
//if including a half-star, replace this comment with the code to do so.
for (i = rating+1 to maxRating inclusive) {
    print "<span>☆</span>"
}

but unless you have a half-filled star character, you won't be able to use that in your output. You might try using the ½ character instead.


Example 3:

The eBay example OP links to uses source like this:

   <span class="display-text-rating">3.7 stars</span>
   <div class="star-rating-section" title="3.7 out of 5 stars">
     <span class="star-rating" role="img" aria-label="3.7 stars">
         <i class="fullStar"></i>
         <i class="fullStar"></i>
         <i class="fullStar"></i>
         <i class="midStar"></i>
         <i class="emptyStar"></i>
      </span>
    </div>

The first line is the printed text showing the rating in text form.
The div title shows that information on mouse hover.
The elements w/class attributes inside the span could easily be programmatically generated as in example 2. The CSS could be set to use different images for fullStar, midStar, and emptyStar. This generation process could be repeated for each user in the section where the users' individual ratings go.

Example 3 has the disadvantage of visually rounding to the nearest half-star (and example 2, to the full star), while example 1 permits more fine-grained distinction of fractional stars without requiring extra programming or image creation. Deciding on the appropriate level of rounding is a question for UX.SE (and if anyone does care enough to ask it, please edit in a link here).

查看更多
登录 后发表回答