Last active
May 4, 2022 21:56
-
-
Save darvil82/3c5ce73c7ac7ad10e269ca5c17f3151b to your computer and use it in GitHub Desktop.
Envelope
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="envelope"> | |
<div class="wrapper"></div> | |
<div class="content"> | |
<h1 class="title">This is a letter for you</h1> | |
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Corporis tenetur quasi fugiat sed temporibus possimus. Omnis voluptatem totam nemo facere, cumque officia. Tempore unde quis adipisci natus placeat corporis sed. | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const envelopes = document.querySelectorAll(".envelope") | |
envelopes.forEach(e => { | |
let lastTime = 0 | |
e.addEventListener("click", () => { | |
if (new Date() - lastTime <= 1000) return | |
if (e.classList.contains("open")) { | |
e.classList.add("close") | |
e.classList.remove("open") | |
e.addEventListener("animationend", | |
() => e.classList.remove("close"), | |
{ once: true } | |
) | |
} else { | |
e.classList.remove("close") | |
e.classList.add("open") | |
} | |
lastTime = new Date(); | |
}) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*, *::after, *::before { | |
box-sizing: border-box; | |
} | |
body, html { | |
height: 100%; | |
} | |
body { | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
background-color: #333; | |
font-size: 1.3em; | |
} | |
.title { | |
margin-top: 0; | |
font-size: 1.5em; | |
} | |
.envelope { | |
$content-rotation: 15deg; | |
max-width: 600px; | |
min-height: 300px; | |
background-color: #eee; | |
box-shadow: inset 0 0 2em rgba(0 0 0 / 25%); | |
position: relative; | |
border: 2px solid #aaa; | |
filter: drop-shadow(0 0 1.25em rgba(0 0 0 / 50%)); | |
border-radius: 10px; | |
transition: .25s; | |
perspective: 1000px; | |
cursor: pointer; | |
// the content of the letter | |
.content { | |
padding: 1em; | |
margin: .25em; | |
padding-bottom: 3em; | |
background-color: #ffc; | |
box-shadow: | |
inset 0 0 2em rgba(0 0 0 / 20%), | |
inset 0 0 .25em rgba(0 0 0 / 25%); | |
transition: .75s; | |
border-radius: 4px; | |
filter: drop-shadow(0 0 .5em rgba(0 0 0 / 20%)); | |
} | |
// flap | |
&::before, &::after { | |
content: ""; | |
position: absolute; | |
inset: 0; | |
height: 40%; | |
clip-path: polygon(100% 0, 100% 10%, 50% 100%, 0 10%, 0 0); | |
transform-origin: top; | |
transition: .5s .75s; | |
border-radius: 7px; | |
z-index: 2; | |
} | |
// inner part of the flap | |
&::after { | |
background-image: conic-gradient(from 180deg at 50% 100%, #bbb 80deg, white 150deg, white, #bbb 300deg); | |
} | |
// flap border | |
&::before { | |
inset: 0.1em; | |
background-color: #ccc; | |
height: calc(40% + .25em); | |
} | |
// for the wrapper of the letter | |
.wrapper, .wrapper::after { | |
content: ""; | |
position: absolute; | |
inset: 0; | |
clip-path: polygon(50% 30%, 100% 0%, 100% 100%, 0 100%, 0 0); | |
z-index: 1; | |
} | |
// for the wrapper of the letter | |
.wrapper { | |
background-color: #ccc; | |
border-radius: 7px; | |
overflow: hidden; | |
// for the inner part | |
&::after { | |
background-color: white; | |
box-shadow: inset 0 0 3em 13px #aaa; | |
} | |
} | |
&.close { | |
// moves the wrapper to the top, hiding the content | |
.wrapper, .wrapper::after { | |
z-index: 10; | |
transition: z-index 0s .5s; | |
} | |
.content { | |
animation: move-in 1s forwards; | |
// plays the move-in animation | |
@keyframes move-in { | |
0% { | |
transform: translateY(2em) rotateX($content-rotation); | |
z-index: 10; | |
} | |
70% { | |
transform: translateY(calc(-100% - 2em)); | |
} | |
} | |
} | |
} | |
&.open { | |
// moves the wrapper to the bottom, allowing the content | |
// to be displayed | |
.wrapper, .wrapper::after { | |
z-index: 0; | |
transition: z-index 0s 0.5s; | |
} | |
// plays the move-out animation | |
.content { | |
animation: move-out 1s .25s forwards; | |
@keyframes move-out { | |
40% { | |
transform: translateY(calc(-100% - 2em)); | |
} | |
100% { | |
transform: translateY(2em) rotateX($content-rotation); | |
z-index: 10; | |
} | |
} | |
} | |
} | |
&.open, &:hover { | |
transform: scale(1.05); | |
.content { | |
transition: transform .75s .15s; | |
} | |
// rotates the flaps 180degrees and darkens it | |
&::before, &::after { | |
transform: rotateX(-180deg); | |
z-index: -1; | |
transition: .5s; | |
filter: brightness(0.8); | |
} | |
} | |
// moves the card up a bit | |
&:hover { | |
.content { | |
transform: translateY(-2em); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment