Tutorials / / 5 min read
How to create an animated envelope with Tailwind CSS
Build an animated envelope that opens on hover with only Tailwind CSS: flaps, letter and stamp made with clip-path, transforms and transitions, no JavaScript.
Well, today we are going to create an animated envelope using only Tailwind CSS. No JavaScript anywhere: the whole thing is clip-path shapes, transforms and transitions.
Why an envelope, and what’s the point?
For nothing really, but to show what you can do with Tailwind CSS and clip-path. It’s a great way to create a unique and eye-catching design where you can add a bit of animation and your own personal touch.
Let’s write the markup
The wrapper
We will start by giving the wrapper a width of 650px and an aspect ratio of 16/9. This can be customized to your liking depending on the shape and size of your envelope.
relative: positions the wrapper so the child elements can be positioned absolutely inside it.w-[650px]: sets the width of the wrapper to 650px.mx-auto: centers the wrapper horizontally.group: lets the children react to hovering the wrapper withgroup-hover:variants.aspect-[16/9]: sets the aspect ratio of the wrapper to 16/9.flex: makes the wrapper a flex container. This is a key class for the envelope, otherwise the layers would look like a mess.
<div
class="relative w-[650px] mx-auto group aspect-[16/9] flex items-center justify-center"
>
<!--- Rest of the content --->
</div>The inside letter
When the envelope is opened it shows a letter inside, so let’s create it.
absolute: positions the letter inside the wrapper. This is important for the letter to sit behind the flaps.flex flex-col items-start justify-start: stacks the letter content in a column, aligned to the top left.px-16andpy-10: padding inside the letter (4rem horizontally, 2.5rem vertically).bg-background: the letter’s paper color.w-full h-full: the letter fills the envelope.transition-all duration-300: animates the letter smoothly.group-hover:duration-1000: slows the animation down to 1000ms while the envelope is open.group-hover:-translate-y-36: slides the letter up by 9rem when you hover over the envelope.
<div
class="absolute flex flex-col items-start justify-start w-full h-full px-16 py-10 bg-background transition-all duration-300 group-hover:duration-1000 group-hover:-translate-y-36"
>
<!--- The letter content goes here--->
</div>The center stamp or ribbon
This is a “modern” stamp, a way of closing the envelope.
bg-[#edeef0]: sets the background color to #edeef0.w-16 h-full: a 4rem wide ribbon running the full height of the envelope.uppercase text-[#0c0d10] font-medium: the ribbon label styling.flex items-center justify-center: centers the label.z-40: keeps the stamp above the flaps. This is important for the stamp to be positioned correctly.group-hover:opacity-0: fades the stamp out when the envelope opens.transition-all duration-1000: animates it over 1000ms.group-hover:-translate-y-96: slides it up by 24rem as it fades.
<div
class="bg-[#edeef0] w-16 uppercase text-[#0c0d10] h-full flex items-center z-40 justify-center font-medium group-hover:opacity-0 transition-all duration-1000 group-hover:-translate-y-96"
>
<div class="-rotate-90">Lexington</div>
</div>Let’s create the envelope shape
On this part we have four divs, each one representing a different part of the envelope. We create the shape with clip-path: each layer is a polygon defined by a series of x and y coordinates, relative to the top left corner of the envelope, and the polygon closes by connecting the first and last vertices.
The top, which is where the letter comes out of the envelope
transition-all duration-1000: animates the flap.z-10: keeps the top flap above the letter while closed.bg-gradient-to-b: a top-to-bottom gradient for the flap.absolute: stacks the layer inside the wrapper.
Only for the top layer
group-hover:duration-100: speeds the flap up on hover. This is important to add only on the top layer, because it has to get out of the way before the letter comes out of the envelope.group-hover:[clip-path:polygon(0_0,_100%_0,_100%_0,_0_0)]: collapses the flap’s polygon to a flat line when the envelope is hovered.
<!--- Top -->
<div class="transition-all duration-1000 group-hover:duration-100 z-10 bg-gradient-to-b from-[#808698] to-[#51576c] absolute group-hover:[clip-path:polygon(0_0,_100%_0,_100%_0,_0_0)] w-full h-full [clip-path:polygon(0_0,_100%_0,_95%_55%,_5.5%_55%)]"></div>
<!-- left -->
<div class="transition-all duration-700 absolute w-full h-full bg-[#4f576e] [clip-path:polygon(0_0,_0%_100%,_8%_51%)]"></div>
<!-- right -->
<div class="transition-all duration-700 absolute w-full h-full group-hover:rounded-tr-none bg-[#4f576e] [clip-path:polygon(100%_0,_100%_100%,_92%_51%)]"></div>
<!--- Bottom -->
<div class="transition-all duration-700 absolute w-full h-full bg-gradient-to-b from-[#0c0d10] to-[#4f576e] [clip-path:polygon(4%_50%,_96%_50%,_100%_100%,_0%_100%)]"></div>The final markup
<div
class="relative w-[650px] mx-auto group aspect-[16/9] flex items-center justify-center"
>
<div
class="absolute flex flex-col items-start justify-start w-full h-full px-16 py-10 bg-background transition-all duration-300 group-hover:duration-1000 group-hover:-translate-y-36"
>
<div class="flex justify-between w-full">
<div>
<p class="font-medium text-foreground tex-tsm">Michael Andreuzza</p>
<p class="text-xs text-zinc-500">
123 Fake Street <br />
New York <br />
NY 10001
</p>
<p class="mt-6 text-xs font-medium text-zinc-500">Billed to</p>
<p class="mt-1 text-sm font-medium text-foreground">Juan Perez</p>
<p class="text-xs text-zinc-500">
456 Fake Street <br />
Narnia <br />
NY 10002
</p>
</div>
<div class="text-sm uppercase font-sembold">Michael and Co</div>
</div>
<div class="mt-8">
<p class="font-medium text-foreground tex-tsm">Dear Mr. Perez,</p>
<p class="text-xs text-zinc-500">
I hope this letter finds you well. This is a reminder that payment for
services rendered by Michael and Co. is now due. Please find the details
of the invoice below:
</p>
</div>
</div>
<!--- Stamp -->
<div
class="bg-[#edeef0] w-16 uppercase text-[#0c0d10] h-full flex items-center z-40 justify-center font-medium group-hover:opacity-0 transition-all duration-1000 group-hover:-translate-y-96"
>
<div class="-rotate-90">Lexington</div>
</div>
<!--- Top -->
<div
class="transition-all duration-1000 group-hover:duration-100 z-10 bg-gradient-to-b from-[#808698] to-[#51576c] absolute group-hover:[clip-path:polygon(0_0,_100%_0,_100%_0,_0_0)] w-full h-full [clip-path:polygon(0_0,_100%_0,_95%_55%,_5.5%_55%)]"
></div>
<!-- left -->
<div
class="transition-all duration-700 absolute w-full h-full bg-[#4f576e] [clip-path:polygon(0_0,_0%_100%,_8%_51%)]"
></div>
<!-- right -->
<div
class=" transition-all duration-700 absolute w-full h-full group-hover:rounded-tr-none bg-[#4f576e] [clip-path:polygon(100%_0,_100%_100%,_92%_51%)]"
></div>
<!--- Bottom -->
<div
class="transition-all duration-700 absolute w-full h-full bg-gradient-to-b from-[#0c0d10] to-[#4f576e] [clip-path:polygon(4%_50%,_96%_50%,_100%_100%,_0%_100%)]"
></div>
</div>Conclusion
In this tutorial we created an animated envelope using Tailwind CSS and clip-path. Nothing trivial, but it’s a great way to add a bit of personal touch to your designs. You can customize the shape and size of the envelope to fit your needs. Remember to adapt it to your specific use case and make it more user-friendly, responsive and accessible.
Hope you enjoyed this tutorial and have a good day!
/Michael Andreuzza