Let’s create a Valentine’s Day Letter using HTML, CSS, and JavaScript. This interactive project will feature a beautifully styled love letter that opens with an animation when hover, creating a heartfelt and engaging experience.
We’ll use:
- HTML for structuring the letter.
- CSS for styling with a romantic theme.
- JavaScript for heart seal.
Let’s get started on building the Valentine’s Day Letter. Whether you’re a beginner or an experienced developer, this project is a fun way to add creativity and interactivity to your web designs. Let’s spread some love through code! ❤️
HTML :
This HTML code creates a fun, interactive Valentine’s Day card. When the envelope is hovered, it animates to reveal a 3D card with a playful message. The card has a front cover with the text “Happy Valentine’s Day” and a humorous message inside, declaring love and “questionable air quality.” The heart seal on the envelope adds a cute touch, and it fades in/out when the envelope is interacted with. The external styles and JavaScript (in the linked style.css
and script.js
) manage the animations and appearance.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Valentine's Day card</title> <link href="https://fonts.googleapis.com/css2?family=Annie+Use+Your+Telescope&family=Petemoss&family=Roboto:ital,wght@0,100..900;1,100..900&family=Shantell+Sans:ital,wght@0,300..800;1,300..800&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> </head> <body> <div class="envelope"> <div class="envelope-lid"></div> <div class="envelope-lid envelope-lid-secondary"></div> <div class="card-wrapper"> <div class="card"> <div class="card-cover"> <div class="card-side card-side-primary"> <h1 class="card-title"> <span class="card-title-secondary">Happy</span> <span class="card-title-main">Valentine <span class="card-title-apostrophe">❤️</span>s</span> <span class="card-title-secondary">Day</span> </h1> </div> <div class="card-side card-side-secondary"></div> </div> <div class="card-body"> <p>To my love,</p> <p>From the moment I first saw you, I knew I wanted to smell your farts forever. Here's to a lifetime of love, laughter, and questionable air quality — </p> <p>Happy Valentine's Day!</p> </div> </div> </div> <div class="heart-seal"></div> </div> <script src="./script.js"></script> </body> </html>
CSS :
This CSS code creates an animated envelope and card interaction. The envelope, when hovered, animates the card to rotate, revealing its contents with a 3D effect. The card’s cover also rotates, and the envelope lid opens in a stacking manner. A heart seal is placed on the envelope, fading in and out. The overall design features soft colors, smooth transitions, and an engaging 3D interaction on hover.
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: "Roboto", serif; background-color: #FFC6C6; } .card-wrapper { perspective: 1000px; transform: rotate(-90deg); } .card { width: 180px; height: 280px; background-color: #fff; border: 1px solid; transform-style: preserve-3d; will-change: transform; transition: transform 250ms; box-shadow: inset 5px 0 10px rgba(0, 0, 0, 0.1); } .envelope:hover .card { transform: rotateY(-15deg); transition-delay: 1750ms; } /* Card cover styling */ .card-cover { position: absolute; inset: 0; text-align: center; outline: 1px solid #000; transform-style: preserve-3d; transform-origin: left; transition: transform 500ms 0ms; } .envelope:hover .card-cover { transform: rotateY(-135deg); transition-delay: 2250ms; } .card-side { position: absolute; inset: 0; backface-visibility: hidden; background-color: #fff; display: grid; place-items: center; } .card-side-secondary { background-color: #fff; transform: rotateY(180deg); box-shadow: inset -5px 0 10px rgba(0, 0, 0, 0.1); } .card-title { position: relative; font-weight: 300; text-align: center; user-select: none; } .card-title span { display: block; } .card-title-secondary{ font-size: 16px; letter-spacing: 3px; text-transform: uppercase; } .card-title-main { font-family: "Petemoss", serif; font-size: 64px; font-weight: 400; } .card-title-apostrophe { position: absolute; top: 34px; right: 8px; font-size: 8px; } /* Card body styling */ .card-body { font-family: "Shantell Sans", serif; padding: 14px; } .card-body p { font-size: 10px; font-weight: 300; } .card-body p+p { margin-top: 10px; } /* Envelope styling */ .envelope { width: 300px; height: 200px; background-color: #fff; display: grid; place-content: center; cursor: pointer; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 0 1px #000; } .envelope::after { content: ''; position: absolute; inset: 0; border-top: 75px solid transparent; border-right: 150px solid white; border-bottom: 125px solid white; border-left: 150px solid white; } .envelope:hover .card-wrapper { animation: show-card 1000ms 600ms forwards; } .envelope:not(:hover) .card-wrapper { animation: hide-card 1000ms forwards; } /* Keyframes */ @keyframes show-card { 50% { transform: translateY(-75%) rotate(-90deg); z-index: -1; } 100% { transform: translateY(0) rotate(0deg); z-index: 10; } } @keyframes hide-card { 0% { z-index: 10; transform: rotate(0deg); } 50% { transform: translateY(-75%) rotate(-90deg); z-index: -1; } 100% { transform: translateY(0) rotate(-90deg); } } /* Card lid styling */ .envelope-lid { position: absolute; inset: 0; z-index: 1; } .envelope-lid::before, .envelope-lid::after { content: ''; position: absolute; top: 0; width: 1px; height: calc(100% - 31.85px); background-color: #000; } .envelope-lid::before { left: 0; transform: rotate(-63.1deg); transform-origin: top left; } .envelope-lid::after { right: 0; transform: rotate(63.1deg); transform-origin: top right; } .envelope-lid-secondary { background-color: #fff; clip-path: polygon(50% 38%, 0 0, 100% 0); transition: transform 500ms 1000ms; transform-origin: top; } .envelope:hover .envelope-lid-secondary { transform: rotateX(180deg); transition-delay: 100ms; animation: open-lid-stacking 500ms forwards; } .envelope:not(:hover) .envelope-lid-secondary { animation: close-lid-stacking 1250ms forwards; } @keyframes open-lid-stacking { 50% { z-index: 1; } 100% { z-index: -1; } } @keyframes close-lid-stacking { 0%, 50% { z-index: -2; } 100% { z-index: 1; } } /* Heart Seal */ .heart-seal { position: absolute; top: 37%; left: 50%; transform: translate(-50%, -50%); width: 36px; height: 32px; background-image: url("heart-seal.png"); background-size: cover; background-repeat: no-repeat; z-index: 2; opacity: 1; transition: opacity 2s ease; }
JavaScript:
This code controls the opacity of a heart seal element when hovering over an envelope. When the mouse hovers over the envelope, the heart seal fades out instantly. When the mouse leaves the envelope, a timeout is set to fade the heart seal back in after 1.5 seconds, with a smooth transition of 0.3 seconds. The transition is applied to the opacity property of the heart seal for a smooth effect.
const envelope = document.querySelector('.envelope'); const heartSeal = document.querySelector('.heart-seal'); let timeoutId; envelope.addEventListener('mouseover', () => { clearTimeout(timeoutId); heartSeal.style.opacity = 0; }); envelope.addEventListener('mouseout', () => { timeoutId = setTimeout(() => { heartSeal.style.opacity = 1; }, 1500); }); heartSeal.style.transition = 'opacity 0.3s ease';
In conclusion, creating a Valentine’s Day Letter using HTML, CSS, and JavaScript has been a lovely and engaging project. By combining structure, styling, and interactivity, we’ve crafted a beautiful way to share heartfelt messages digitally
If your project has problems, don’t worry. Just click to download the source code and face your coding challenges with excitement. Have fun coding!