

How to Make Easy & Flexible Star Ratings - Airbnb-Nerds
http://nerds.airbnb.com/quick-tip-making-star-ratings-with-one-image

======
mhartl
This is a great discussion of the mechanics of rendering star ratings in a
browser. I'd love to see a companion theory post on how to intelligently
compute and rank such ratings. The arithmetic mean is notoriously sensitive to
outliers, and the consequences are sometimes severe: I know a resort in
Thailand that used to be ranked #1 on TripAdvisor on its island (Koh Phangan),
only to fall to #17 after a 1-star review. (The tragedy is that, if you read
the review, it's clearly positive—the reviewer evidently thought that 1-star
was best. D'oh!) In addition, any sensible ranking should take into account
statistical significance, so that (say) a 4.6 ranking consisting of 45 reviews
(possibly) gets ranked above a 5-star ranking consisting of one review. How
does Airbnb handle these cases, or does it just punt by calculating and
sorting the arithmetic mean?

~~~
gwillen
Use the algorithm given here:

[http://www.evanmiller.org/how-not-to-sort-by-average-
rating....](http://www.evanmiller.org/how-not-to-sort-by-average-rating.html)

~~~
samstokes
Also the response article at [http://masanjin.net/blog/how-to-rank-products-
based-on-user-...](http://masanjin.net/blog/how-to-rank-products-based-on-
user-input.html) is interesting.

~~~
BerislavLopac
Thank you guys, I'm just working on an app that requires calculating scores on
user input, and these articles are pure gold! :)

------
smackfu
It's interesting that the year 2000 way to do stars would be to have a full,
empty, and half star GIF, and just to display however many stars you need by
doing a loop.

So, when this article says "The goal is to avoid having a sprite that looks
like this" where the sprite has all the values of stars in a line... why did
people switch to doing it that way in the first place? Like the article says,
it's a pain to maintain, has lots of pixels, and is not resizable.

~~~
funkah
Well, if you do it that way you can change the whole rating by just changing
the class name, after you set up all the background-position rules for all the
different rating classes. I guess that's why?

~~~
michaeldhopkins
With a loop you only need to pass in the rating. Get the modulus and then the
floor. Render as many full stars as the floor, a half star if modulus was more
than zero, then render an empty star as far as the number of full stars + half
stars rendered was less than the number of stars that should be displayed
(e.g. 5.)

That's way less work than all that CSS.

~~~
ricardobeat
This method leaves all styling in your HTML/server-side code, which is a pita.

~~~
BerislavLopac
In an app I'm making, each group of items can have a different rating size, as
defined by the group's admin. So the sprite with a fixed number of stars
wouldn't work.

Essentially, I see a number of stars as just a different sort of a "progress-
bar"-like graphic, so it's not necessary to set individual stars in the HTML.
Just set it as a horizontally-repeating background, with predefined "steps" od
the overlay, and the only number you need to pass from the server is the step
level. This can even show a partial star if you want.

P.S. I haven't read the OP article prior to writing this comment; that's
essentially what they're advising there.

------
pothibo
I liked how you guys present some of the stuff you create. However, I'm not a
huge fan of star rating. I know it's in use everywhere but I feel that it's
such a flawed rating system that we need to think twice before using star
ratings.

I think that Facebook's like is a good concept that can replace stars rating
(a like is a like, no negative feedbacks, and you know that you either like
something or you didn't).

Star ratings is too complex, I mean, something I rate 4 star is very different
than somebody else's 4 star rating.

Maybe this isn't the place to discuss this but I wanted to let the word out ;)

~~~
mikehearn
This is touched on in some of the other posts, so I won't belabor the point,
but the issue with only positive feedback is that there isn't a way to
identify items that are popular but also controversial.

For example, an Airbnb venue with 5,000 likes would be considered 'better'
than one with 500. But add in negative feedback, and consider if the same
venue with 5,000 likes also had 4,500 dislikes, while the venue with 500 likes
only had 50 dislikes.

Negative feedback helps us discern between if something is 'better' or simply
'popular' -- the latter can be gamed with marketing, while the former is much
harder.

~~~
ajtaylor
That is a great point. At $work, we're about to revamp how we do ratings. The
idea was to only consider positive feedback, but maybe we should figure out
how to include negative feedback too. But that brings up the question of how
to avoid the spammers, scammers and idiots that inevitably popup?

------
v01
One thing I would suggest to all you coders out there... PLEASE place a demo
within the post in which you are writing the tutorial.

For example big demo button on CodDrops:
[http://tympanus.net/codrops/2011/10/12/flexible-slide-to-
top...](http://tympanus.net/codrops/2011/10/12/flexible-slide-to-top-
accordion/)

------
Dylanfm
The HTML5 meter element lends itself to star ratings perfectly. Using divs
with classes seems a bit old-school for today, although the blog post does say
how they don't want to use JS for this.

I wrote a Raphael powered polyfill for this
<http://dylanfm.github.com/jquery.ratemate/>. Although it requires Raphael
(and JS), at least it's a bit more semantic and has a non-JS fallback in
browsers that have native support for the meter element. The plugin also
provides a way for controlling star ratings on input type number or range
elements. However, this really isn't worth using if you're not including
Raphael already (fairly large library). I'm thinking about making a canvas
alternative.

------
Aloisius
On a side note, if you have 6 different ratings on one page plus an overall
rating, should they all be stars and all in the same color?

------
llgrrl_
This is the code that should go to the server side for calculating star
ratings:

 _Star Ratings_

I’ve been awfully busy programming lately. My Django-based side project is
coming along well and I hope to have it ready for use in a few weeks. Please
don’t ask more about it, that’s really all I can say for now. Anyways, I came
across an interesting little math problem today and was hoping some skilled
programmers out there could come up with a more elegant solution than mine.

 _Problem: Star Ratings_

People can rate cheeseburgers on my website with a star rating of 0-5 stars
(whole stars only), 5 being mighty tasty and 0 being disgusting. I would like
to show the average of everyone’s ratings of a particular cheeseburger to the
nearest half star. I have already calculated the average rating as a float
(star_sum) and the total number of people that rated the particular
cheeseburger (num_raters). The result should be stored as a float in a
variable named “stars.”

 _My Solution (in Python):_

    
    
      # round to one decimal place and
      # separate into whole and fractional parts
      parts = str(round(star_sum/num_raters, 1)).split('.')
      whole = int(parts[0])
      frac = int(parts[1])
    
      if frac < 3:
        ___frac = 0
      elif frac > 7:
        ___frac = 0
        ___whole += 1
      else:
        ___frac = 5
    
      # recombine for a star rating rounded to the half
      stars = float(str(whole)+’.'+str(frac))
    

Mmmm… In-N-Out Burgers… Please leave a comment if you’ve got a better
solution.

~~~
teej
Please don't do that. Here's a one liner:

    
    
        round( 2.0 * star_sum / num_raters) / 2.0

------
ricardobeat
Pretty nice. It's missing the actual content though (the rating), so it's
completely inaccessible to search engines, scrapers, screen readers and the
like.

------
jwdunne
I would do it another way. I'd have an on state and off state graphic as a
sprite. There'd be two divisions, one laid on top of each other. The bottom
layer would be the off state tiled horizontally statically at the width that
is the number stars your ratings setup uses by the width of you on-off state
graphic. The layer on top would be the on state with a width determined by an
online style - CSS accepts percentage as a unit which can be worked out
trivially. I find this is far more flexible that setting static widths in the
CSS. You only haVe to set one width: the number of stars. Other things can be
worked out programmatically and cached if needed.

------
swah
"Its very easy but I won't put one of those on this page."

------
pchristensen
This was a great, easy to read and understand tutorial.

------
huxley
A bit disappointed that the ratings don't degrade gracefully to a form with a
dropdown menu or radio buttons.

------
rhdoenges
Why are the gists in a non-fixed width font?

------
dfischer
Great use of SASS. I approve!

