Star-rating with simple animations (the saga continues)
Andrew Bone

Andrew Bone @link2twenty

About: A British web developer, that is passionate about web accessibility.

Location:
Britain, Europe
Joined:
Jun 8, 2017

Star-rating with simple animations (the saga continues)

Publish Date: Jul 7 '21
34 8

I don't know if you've all noticed but there have been a lot of star rating posts being published on Dev these past few days. Including an entry from me. The main problem with my entry was, that while it was accessible, it was a little boring. Now I know star ratings need to be functional so I won't be doing anything crazy, like using one giant star, but I will be adding some simple animations.

The saga so far

If you want to read through the articles written so far check out. @inhuofficial, @lapstjup, @madsstoumann, @afif and @siddharthshyniben. If you'd like to throw your own hat into the ring with a different way to achieve a star rating (it doesn't even have to be with web tech) feel free to write a post and let one of us know! 😊

The code

I'm not going to change my html, if it ain't broke; don't fix it. So if you want to look at the html and the logic behind it you'll need to have a look at my last post.

The animations

I didn't want anything to excessive so I'll be adding a little shake and pulse animation when a new star is selected.

The shake

The shake is a transform rotate which is in a keyframe this allows us to have a more complex animation.

.star-rating>input:checked+label>span.star {
  animation: shake 820ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  transform: rotateZ(0);
}

@keyframes shake {

  10%,
  90% {
    transform: rotateZ(-1deg);
  }

  20%,
  80% {
    transform: rotateZ(2deg);
  }

  30%,
  50%,
  70% {
    transform: rotateZ(-3deg);
  }

  40%,
  60% {
    transform: rotateZ(3deg);
  }
}
Enter fullscreen mode Exit fullscreen mode

The pulse

The pulse is slightly more complex, but only slightly. We have to use a before and give it our star as its content, this is so our pulse can match the shape. After that we just scale our pseudo element and make it more transparent.

.star-rating>input:checked+label>span.star::before {
  content: '★';
  pointer-events: none;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  color: currentColor;
  -webkit-text-stroke: 0;
  animation: pulse 820ms cubic-bezier(0.36, 0.07, 0.19, 0.97) forwards;
  transform: scale(1);
  opacity: 0;
}

@keyframes pulse {
  10% {
    transform: scale(1);
    opacity: 1;
  }

  90% {
    transform: scale(3);
    opacity: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

Prefers Reduced Motion

The aim is to keep this component accessible and part of that is supporting people that can't handle too much motion and thusly have the prefers-reduced-motion rule enabled in their browser.

It's pretty simple to add support for this. For our shake we can just set the animation back to initial, meaning it never plays, and for our pulse we can hide the entire before element.

@media (prefers-reduced-motion) {
  .star-rating>input:checked+label>span.star {
    animation: initial;
  }

  .star-rating>input:checked+label>span.star::before {
    display: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

It really is that simple to implement prefers-reduced-motion and it can be so helpful for many people.

The result

Where here it is, the result. As I said earlier the HTML and functionality haven't changed but now we have a little pizazz.

Signing off

As always if you have any questions or feedback please leave a comment and I'll take a look. It'd be great if you could have a look at the other posts on this topic too they're really good and everyone has a different take.

I do hope this sort of post is helpful, would you be interested if this became a regular thing? Maybe a monthly topic that had a few people posting their take?

Thank you so much for reading.
🧙‍♂️❤️❤️🦄🐘🧠🤖👾

Comments 8 total

  • GrahamTheDev
    GrahamTheDevJul 7, 2021

    In stark contrast to my post that started this all, this one might kickstart more ideas for interactivity. I am glad you used prefers-reduced-motion as some people may find animations startling. So from an accessibility point of view this one cuts the mustard. Just when I think this will end some upstart decides to restart everything, I am starting to think this will never end!

    I will see myself out...

    • Andrew Bone
      Andrew BoneJul 7, 2021

      Yeah prefers-reduced-motion was all I really brought to the table, I think, but I do think it was an important thing to mention.

      You boldened the t in upstart, so close 😉.

  • Temani Afif
    Temani AfifJul 7, 2021

    Oh, you are fighting with animation now! You are using one of my superpower against me and you will regret it soon ...

  • Andrew Bone
    Andrew BoneJul 7, 2021

    As with the last post I've converted this into a react component.

  • Simon Barker
    Simon BarkerJul 8, 2021

    Great improvement Andrew, your CSS is way above mine, I guess that's why I'm a full stack trogledite though 🤣

    • Andrew Bone
      Andrew BoneJul 8, 2021

      Haha, thanks. I really enjoy writing CSS 😁.

Add comment