Build a Flexible Ribbon Banner in Tailwind CSS Tutorial (10 exercises)

BONUS: Add Multiple Style Options

With all the work and thinking that went into building this ribbon banner, I think it’s worth spending a little extra effort to turn our ribbon into a reusable component that can receive a few options, such as:

  • what corner it should wrap around
  • what size the banner should be

Figuring out the “diff” between component variations

The quickest way to identify what CSS needs to change is to duplicate the ribbon component, and try rebuild it for a different “scenario”.

Let’s start with the corner positioning.

Ribbon corner positioning

After duplicating the ribbon and rebuilding it on the left corner, here’s the differences in code I have identified, marked as {placeholder_name} variables:

Essentially, all we need to change is classes that affect the vertical and horizontal positioning for absolute elements, as well as the rotation and transform-origin values for the banner.

Everything else remains the same!

As you could imagine, it would be quite easy to abstract those changes to a component prop or option.

The implementation depends on what programming/templating language you are using, but let’s take the example of JSX.

We’d setup a quick little “styles lookup” JavaScript object like so:

I haven’t completed all the values, but you get the point: each possible position (like top-right, bottom-left) has a key in the styles lookup object.

Inside of that, each element that needs changes will have a list of classes that should be dynamically applied to it.

If we were creating a Ribbon component, that component should accept a position prop:

Now that we can reach for the correct the dynamic positionStyles based on the position prop passed to the component, all we need to do is replace the {placeholder_name} values with those styles:

And that’s it!

Now, we can use and place our Ribbon component like this:

Pretty cool, huh?

Ribbon size

Changing the ribbon size follows the same principle, but is much, much quicker to implement.

The only class that change to adjust the ribbon dimensions is the width.

We’d create a size styles lookup object that looks like this:

And now, all we need to do is replace the “hardcoded” width class in our ribbon with sizeClasses[size]!


Let me walk you through my thought process here. First thing I'll do is add a comment on this one, which is Top Right. I will duplicate everything, and this one is going to be Top Left. Right now, we have two elements exactly overlapping, so we don't see the difference, but let's start the migration to the top-left corner and see what sort of elements we have to change.

The first thing we have to do is, instead of -right-2, I'm going to go -left-2 here. Here's the second ribbon showing up. Next, I think we should change the rotation. Down here, instead of rotate-45, I will go -rotate-45. With that, we have absolutely destroyed our component for the time being, but let's fix that.

Remember, we put our pin on the bottom right here, which is down here, and our ribbon, which was up here like this, went [jjjooop], and how is like that. We need to change the pin from bottom-right to bottom-left. Instead of absolutely positioned to bottom and right-, once again, we want to change to bottom and left-. Nice.

We can see so far a lot of the changes are just changing right to left. Finally, we want to fix up our dark shade spots here. The first one should go to bottom- and left-, and the second one should go from top- and right-. Just for fun, let's change all the instances of amber for this one to green, and perhaps the yellow on hover could be emerald.

We'll also change the text. This one will say Top left, and we'll make it a bit smaller with w-, let's try 24. It might be a bit too small. Eh, that's all right.

Let's do the process one more time, but hopefully, you're already noticing the sort of elements that need to change. This one will be -bottom-2 and -left-2. The rotation will go back to positive, rotate-45, but this time, the origin should be origin-top-left, I think, and so should the absolute positioning of top-, left-. Nice.

Let's fix our darker shade, so top-, left-, and bottom-, right-. Let's change this one from green to purple, and the hover state will be violet. That's pretty good. This one can say Bottom left. We need to increase the size a little bit, so 28.

Look at our ribbons. They look pretty cool. As you've noticed, switching the corner of the ribbon was pretty simple. There's not that many classes changing. We've noticed a pattern. It's mostly the top-left bottom-right positioning and rotate that changes and then the width and colors, of course.

Now, we have our three blocks of HTML representing these three ribbons. We could stop there, but we may as well create a quick little component with some props.