Create a Wraparound Effect
The wraparound effect
First, let’s set the
overflow-hidden class back on the container:
Oh wow - what a difference!
We’re super close.
Darker color shapes to create depth
To “sell” our wraparound effect, we’re going to use darker shades of the
We want to emulate the band wrapping behind the card, and all we need to do this is fill two little squares with some color.
Let’s draw imaginary shapes one more time:
If we’re clever about the stacking order of our elements, we can get away with doing two little darker squares, and absolutely position them where we need.
absolute parent resets the
relative context for its children.
So, let’s create two squares inside our ribbon container (the one we removed the just background color for):
Few things to note here:
- We use
w-2for the dimensions of the squares, because it’s the amount of offset the ribbon has in relation to the card. Check the
-top-2 -right-2classes on the container!
- We use
bg-amber-500, a slightly darker color, to emulate those shapes being in the shadows, behind the ribbon, and therefore darker.
- Both squares are absolutely positioned to the
bottom-rightedges of the container square - just like we did in our “imaginary shapes” drawing in Figma.
Let’s take a look!
Hmmm. The position is right, but our stacking order is wrong: the little squares are supposed to appear behind the ribbon, not in front!
Do we slap a
z-index on this banner?
No, wait. We don’t need to!
The HTML source order affects how layers stack
Right now, our little squares are on top of the banner because those elements are defined below the ribbon in the HTML.
Source order matters in your HTML. For elements within the same stacking context, think of it as layers of document. Each new line of HTML adds a new layer on top of the previous one.
Let’s see what happens if we just moved our wraparound decorative squares above the ribbon markup:
Nothing else changed in the code. Just the source order. Here’s what we get now:
At this point, our ribbon is nearly complete. The last thing we want is to round those edges a bit, so the wraparound effect gets some more depth and feels even more real.
This one is really simple.
If you remember to think about the invisible parent container!
Rounding the invisible container
Our parent container is responsible for clipping and hiding anything that bleeds outside of its own surface.
That means that if we give rounded corners to that parent container, we should observe a nice rounding of our ribbon’s edges!
Let’s try it:
And with that…. we are done!
Pheeew, that was quite something. I hope you enjoyed this tutorial and learned a thing or two.
Step one is pretty easy. We've already done it before in this tutorial. I'll add a class of overflow-hidden, remembering the shape of that square remind the ribbon. This will crop out the elements. Immediately, this thing starts to look really cool.
Next, I want to add darker elements behind the corners. We want one little square here and one little square there. If we look at the parent component, remember, we are offset by top-2 and right-2 negative. Technically, if we had a square of level 2 by level 2, which is eight pixel by eight pixel, it should fill this exact little gap here.
Once again, the container here has a position of absolute. If I create a child element inside of it, it'll treat that container as its relative context. I have a div with a position of absolute, a height of 2, and a width of 2. Let's give it a bg-amber. The banner itself is 300, so let's go with 500.
Look at this! Straight off the bat, it looks really good. If I zoom in in the browser, it looks exactly like what we want. Notice how this shape appears behind the ribbon, which is what we want. We didn't have to specify any index value.
This is because the source order of the HTML already dictates that. If I had these elements after my anchor tag, the square would now appear above the banner, which completely kills the wrap-around illusion we're going for. Let's move that back up.
Also, note that I did not have to specify top- and left- since it's the default, but I think we should actually do it to be more explicit -- top-, left-. Nothing's going to change, but now we have the blueprints to create the other dark spot on the bottom-right corner. As you can imagine, I'll change this to bottom- and right-. Boom, this by itself is already a perfectly acceptable ribbon.
Let's maybe add some hover state as well to sell it even more. Here we have bg-amber-300. Perhaps on the hover, we could change this to bg-yellow-300, which is slightly different. It would give it this extra little element of attention when you hover over it. I can add this checkmark.
Our last task is to round the ribbon corners. That might seem trickier than it actually is. You may think that you need to start using rounded corner on the bottom-right corner of the little shape there and top-left corner here, but remember we have this invisible container element here that has an overflow-hidden class.
If we round the corners of this element, the cropping will respect the rounded corners. All I have to do is go in the parent container here and go rounded. Let's try lg to make it really obvious. You can see the rounded corners are definitely there. That's probably too much. I think just rounded here will do. It's still a bit too much, so even rounded-sm for small. Here, that's looking really good.
There you have it. Let me remove these comments, and this is all of our code. In about 10 lines of HTML and CSS, we've created this really cool ribbon element that looks great and, as you can imagine, can be quite flexible. You can change the dimensions, the colors, the contents, and also think about changing the positioning.
We're going to have one more bonus lesson where we're going to look at just that.