·

photo credit: the fishing tree : koi pool, seoul, south korea (2009) via photopin (license)

How to create a neat star rating with CSS and JavaScript

So I wrote a simple piece of JavaScript the other day that showcases a neat star rating effect. In this article I’ll not only showcase this effect, but I’ll also explain some of the code that’s going on in it.

Demo

See the Pen Star rating by Giel Berkers (@kanduvisla) on CodePen.


This is the demo. You can hover over the stars and they will animate when hovered. Nothing too fancy-pancy, but there are some interesting things to notice:

  • The stars aren’t a webfont of some kind, but just simple Unicode stars.
  • The animations are done with CSS.
  • It uses a minimal amount of JavaScript to highlight the stars up to the star that is ‘hovered’.

The HTML

The HTML is pretty simple and pretty straight-forward. It’s just a container with some spans containing a star:

Nothing interesting here, let’s move to…

The CSS

The CSS is also quite simple, but let’s take a look at the CSS of the rating box and the individual star elements:

The first thing you’ll notice in the demo is that the stars have a small, but elegant and subtle 3D transformation. It appears as if they are just lying there on the ground. This is done with the transform: rotateX(45deg)  property on the span elements. To set the ‘pivot point’ of these span elements on the bottom, we set the transform-origin  to center bottom , and to give the whole thing a 3D experience we set the perspective  of the parent element (#rating ) to 250px .
Another thing to note here is the hover -class we defined. This is the style the element gets when it’s hovered on: the color and opacity changes, the rotation is set to 0, which causes it to ‘stand up’, and we misuse the text-shadow  to create a glow effect. The transition: all 150ms  we defined on the global span element causes our changes to get animated so it looks super-cool!

Why .hover and not :hover?

You might ask yourself the question now:

“why are you defining the hover style with a class instead of just using the :hover pseudo class?”

It’s a good question, and the answer is simple: when we hover over a star, we want all the stars before the star we are hovering on the become active as well. Although this is not impossible with just CSS, it’s not the most cleanest solution to go for. And: at some point you need to bind a click-event to the span elements, so you are going to have to use JavaScript at some point.

The JavaScript

I wrote the JavaScript in an object-oriented approach, since that is the way how I write JavaScript nowadays. Let’s take a look at the code:

Let’s take a look at the init() -method. What it does is the following:

  • It creates a reference of all the star-elements.
  • It adds a count-number and binds a mouseenter -event to each star.
  • It adds a mouseleave -event to the outer wrapper.

If you look at the enterStarListener() – and leaveStarListener()  you’ll notice that they both execute the same method: fillStarsUpToElement() . This is the method that does all the magic. So let’s just take a look at this method:

Well this is the core of the functionality: it iterates through all stars and checks the following:

  • If the element provided to this method is null , remove the hover-class of this star.
  • If the count-number of this star is higher than the count-number of the element provided to this method also remove the hover-class of this star.
  • Of both of the above is not the case, this star should have the hover-class.

It’s actually very simple logic and it provides a solid functionality for this tiny star rating demo. The only thing that’s left to do is add an event listener that listens to clicks (or taps), but that’s one I’m saving for another article.

Visitors give this article an average rating of 3.3 out of 5.

How would you rate this article?

One thought on “How to create a neat star rating with CSS and JavaScript”

  1. David B Hewes says:

    Where is the article for the event listener that listens to clicks?

Leave a Reply