Ryan S. Chiang

How to Create a Pure Tailwind CSS Star Rating

Updated

3 min read

I've been building Featurable, a review & testimonial management SaaS.

So I've been working with reviews and star rating systems a lot. So here's a brief tutorial on a pure CSS (Tailwind CSS only) five-star rating component.

Here is a preview what we'll be creating:

TailwindCSS Star Rating

Animating the slide down

We want to animate this component to "slide down" like a toast notification.

Let's add this animation to our tailwind.config.js:

javascriptconst config = {
    theme: {
        extend: {
            keyframes: {
                "slide-down": {
                    from: {
                        transform: "translateY(-100%)",
                    },
                    to: {
                        transform: "translateY(0)",
                    },
                },
            },
            animation: {
                "slide-down": "slide-down 0.3s ease-out",
            },
        },
    },
};

Great! Now we can set up our component.

Creating the component

I'll call this component ReviewPopup.tsx:

jsx"use client";

const ReviewPopup: React.FC<{
    isOpen?: boolean,
}> = ({ isOpen }) => {
    return (
        <div
            className={"z-[60] fixed top-6 left-1/2 -translate-x-1/2"}
        >
            <div
                className={clsx(
                    " bg-white p-3 shadow border border-solid border-gray-200 rounded-md",
                    isOpen ? "animate-slide-down" : "opacity-0"
                )}
            >
                <p className="font-bold text-base">
                    How are you enjoying our product?
                </p>
                <p className="mt-1 text-xs text-center text-gray-500">
                    Use the stars below to rate your experience.
                </p>
                <div className="mt-2 flex items-center justify-center">
                    {/* 
                    Stars will go here 
                    */}
                </div>
                <div className="mt-2 flex items-center justify-center">
                    <button
                        onClick={() => setIsOpen(false)}
                        className="text-sm mx-auto text-gray-500 "
                    >
                        Maybe later
                    </button>
                </div>
            </div>
        </div>
    );
};

I want it the popup to be centered horizontally (using translateX), but our animation also uses translateY.

Since we don't want animate-slide-down to overwrite our horizontal translate, I'm using two outer div containers.

Now let's add the stars.

Adding the star rating

Our goal is when a star is hovered, all stars to the left are also highlighted.

To do this, we'll create a CSS class like so:

css.star:hover .star,
.star:hover ~ .star .star-icon {
    @apply fill-gray-400;
}

The element1~element2 operator selects every element2 that is preceded by element1.

Now let's use this class in our component like so:

jsx{
    Array.from(Array(5)).map((_, i) => {
        return (
            <button className="star">
                <StarIcon
                    className={"star-icon h-6 w-6 fill-amber-500"}
                />
            </button>
        );
    });
}

And that's it!

Wrapping up

Now we have a fancy pure CSS star rating component:

TailwindCSS Star Rating

Enjoy, and be sure to check out Featurable if you're looking to improve your social proof, boost conversion rates, and save time + money managing customer feedback.

Ryan Chiang

Meet the Author

Ryan Chiang

Hello, I'm Ryan. I build things and write about them. This is my blog of my learnings, tutorials, and whatever else I feel like writing about.
See what I'm building →.

If you want an alert when I write a new blog post (not often), you can subscribe below:

0

Comments

Leave a Comment

Your email will not be published. Required fields are marked *

2024

2023

© 2024 Ryan Chiang