To be honest, I hardly ever stumble upon a situation that I have trouble finding a satisfying solution to my problem over the internet. And yet it happened to me last week. I was thinking of a way to improve the design of an application that our awesome interns, Asia and Przemek, are making. The app is really simple: it’s for rating submissions of people who want to participate in a Rails Girls event. In the app you can log in, view a whole list of submissions, filter them by the rated/not rated condition and view a single entry. It’s in the single submission screen where you can rate and click previous/next arrows to view another application. People who use the app usually go to the view with a list of unrated submissions, go to the first or the last record, rate it and navigate with arrows to the next one.

Since I always try to find a way to improve user experience, I started thinking what could be done there to make rating many, many, many submissions in a row a pleasant and not a daunting experience. Usually, a user doesn’t even have to scroll down the page, he or she quickly scans a description of a wannabe attendee and rates them on a scale from 1 to 5. I thought it would be a nice touch to add a cute animation to the rating form, one that would make a person feel satisfied and want to click again. I started browsing the internet in search of inspirations for such an animation and I couldn’t find anything that was really satisfying. That’s when I knew that I needed to craft this cute interaction myself. And hell, why not share it with others if they are ever in need of creating a similar experience?

Starability.css rise

I’ve decided to prepare the code in a way, that would be easy to use for everyone. I chose the simplest way: put the code on GitHub in a form of a small library with separate files for each animation. You can find it under the name of Starability in our Lunar repository. The name is a combination of two words that explain library’s purpose best: to star and accessibility (or just ability in general, if you like it better). Why accessibility? Because what I ended up with is a cute rating widget fully accessible by keyboard. Yay! You can go to Starability demo page to play with the animations or visit GitHub repository to see the code. There are only a few versions of the widget for now, but I am hoping to add more soon. ;)

Technique explained

Since I wanted to make rating accessible by keyboard and didn’t want to make the intern’s little application heavy by using loads of JavaScript, I’ve decided to use the accessible star rating widget technique by Lea Verou and enhance it with my animations. To understand the technique better you can read the following code with commentary (you don’t need to understand it to use the library, though!). In short we have a collection of radio buttons, which are in inverted order, and we take advantage of sibling combinators: ~ and +, to target elements that are after the input with :checked state.

Knowing that, we have a fieldset that looks like this:

And we basically float radio buttons to the right, which lists them in the direction from 1 to 5, not as they appear in the markup. The only disadvantage of this technique is that when navigating the stars with left and right arrows, they are highlighted in the reverse direction to what you could expect. It is a bit confusing for us, but it shouldn’t be a problem for a person using a screen reader because the rates will just be read in a descending order. Also navigating with up and down arrows works as expected.

We hide the inputs themselves and add styling to the labels so that they appear as block elements with stars as background images. Label text colour is transparent and will still be read by screen readers, so everyone can know which rank is being marked. I am using background images in labels, not the Unicode characters, as some of the screen readers read the :before and :after pseudoelement content.

Now we are just one step from being able to highlight the labels that appear to the left from the checked input. To achieve this we just need to use this clever selector that takes all labels after the mentioned input with the state :checked.

The rest of the CSS is cosmetic changes. Of course, there is a cherry on the top: animations. They are implemented in a very simple way: all labels have an :after pseudoelement that is hidden until we check one of the radio buttons. Once it is checked, we show the pseudoelement and it triggers its animation.

Accessibility, performance, other long words

To make rating even more accessible, I’ve added a delicate outline that shows us which element is in the focus state at the moment: it is useful for a person that can see but doesn’t navigate the website with a mouse or a touchpad. It is always visible in WebKit based browsers and visible only while navigating with a keyboard in Firefox. If you don’t see a need for that in your app, you can easily disable it by deleting/commenting out 3 lines of code.

Another thing to note is that stars are highlighted on hover. To have this effect we are changing the background image position of a label. This is an action that causes website repaints whenever the hover is triggered, so you if you are a performance junkie you might want to turn that off too. Starability.css readme explains how to disable both of the mentioned behaviours easily.

Customisation? Why not!

If you are well versed with SCSS you can easily adjust the rating widget to your needs, e.g. have a 10 star based system or turn off the previously mentioned outline and hover. It can be done by setting true/false values to the variables and running a gulp task to process files. Of course to have 10 stars system you also need to add additional radio inputs in your HTML. It is explained in detail in the reference.

Grab & enjoy

If you like this small library feel free to use it in any way you want: it’s open source and I don’t mind you just copying and pasting the code to your app – as long as the web is more accessible and beautiful I will be happy! If you have any questions feel free to write a comment here, ping me on snapchat or Twitter.