Introduction
Yesterday i made a private webpage for my freinds birthday that talks about how amazing they are. So i decided i should share how i made this! For the scroll animation i used IntersectObserver
wich i will talk about in another post today so please follow me to see how it works! I'm also a begginer so if you want me to add any improvements please let me know. Make shure to scroll down to see how i made it.
Here it is on codepen:
HTML layout
For the HTML i created 5 section each having a header, text, and an image. Some of the elements in the sections had div
's to seperate the p
and h1
elements from the images horizontally. I gave each section a class name that matches the color i'm gonna give them while for each child element i gave them a hidden class name wich i'll use to give them a scoll animation. For the last section i gave one of the words in the heading a span
element to style it differently later. Each of the images are pictures of my freind, but for this showcase we'll use different images to keep their privacy. Although for the last section i gave it a class name called Final wich will show an image saying "Thank you!" on it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css" type="text/css">
<script defer src="app.js"></script>
</head>
<body>
<section class="darkestPeach">
<div class="hidden">
<img src="https://gifimage.net/wp-content/uploads/2017/10/dancing-cat-gif.gif">
</div>
<div class="hidden">
<h1>Happy Birthday Unicorn!</h1>
<p>Even though i haven't seen your face in centuries. I hope you like this :D</p>
</div>
</section>
<section class="darkPeach">
<div class="hidden">
<h1>Yoshi!</h1>
<p>You're a pretty cool person who plays on the nintendo!</p>
<br>
<h1>Mmm Chezburger</h1>
<p>You like playing roblox! Best free game on Earth! We should play a game one day :o</p>
</div>
<img class="hidden" src="https://media.discordapp.net/attachments/701125768675065917/1030316445445398538/2022-10-13_9.png?width=1246&height=701" class="awards">
</section>
<section class="peach">
<div class="hidden">
<h1>You're an amazing freind!</h1>
<p>
To tell the truth, i didn't think i would be able to make this on time, but i tried my best to give you a showage
of appreciation. Even though we don't talk a lot you're still my freind and i just wanted to show you that it's
not just your family who cares about you. I also made this to help improve my coding skills since i made this
website without any apps or extensions, it's just all code! I don't know a lot about you so i just put some
random images and an aeshetic image at the bottom. I hope you have an amazing year and uhh I'll make something
even better for you next year! (p.s the section above is supposed to be all the hobbies that you master at, i
should've asked more questions to put more hobbies there)
</p>
</div>
<img class="hidden" src="https://media.tenor.com/GdJRGf60YN4AAAAC/hugs-sending-virtual-hugs.gif">
</section>
<section class="lightPeach">
<div class="hidden">
<h1>One word, <span>Fantastic</span></h1>
<p>That's the word i would use to describe you. Even though i don't know a lot about you it makes me wonderous.
Anways your teasy ego is amazing, even though you don't text a lot you text more that Prishaa or the others.
There isn't really anything you should change about you (except for your response times on discord) so keep
being you the that's how you met most of us :).
</p>
</div>
<img class="hidden" src="https://media.discordapp.net/attachments/701125768675065917/1030315397121052762/2022-10-13_7.png?width=1246&height=701">
</section>
<section class="final"><h1 class="move">Thank You!</h1></section>
</body>
</html>
Note: You can make the image to the left and the text to the right or reverse it depending on the order you put them
CSS
To layout the section i gave it a min-height
of 500px
. I then gave each section flex and align-items
to the center while using space-around
to space around each child element. I used gap
and gave it the value of 5rem
to always space the elements apart. Then i made shure the html and body had margin
set to 0 with the height
and width
set to 100%
. I gave the images a width of 300px
with a border radius of 10px
for extra styling. Finally i put a transition of 0.8s
. This is so later the :hover
animation lasts 0.8s
. That animation causes the bottom margin to go up by 20px
with a box-shadow
as well.
For each section class i gave them different colors with some having differnet fonts and some having grid
(for better layout). I gave the span element a font-family
of lobster
. For the last element i gave it a class called move wich has the property margin-right
that has the value of 1000px
(to make shure it doesn't block the image at the bottom).
Lastly i gave hidden class an opacity
of 0
and gave their transform
element translateX(-100%)
. This is how our scroll animation starts so i then give it a transition
of 1s
for all
. Next is the show class, i gave it an opacity
of 1 which is the same as 100%. The transform: translateX
property goes back to 100%
as well. This means that at the end of the animation the content can be fully seen and placed right where it should be.
For the class called Final i gave it a background-image
with a font-family
to have it as a thank you image.
@import url("https://fonts.googleapis.com/css2?family=Dancing+Script&family=Lobster&family=Lora:ital@0;1&family=Poppins:wght@300;400&display=swap");
html,
body {
height: 100%;
width: 100%;
margin: 0;
}
body {
margin: 0;
background-color: #f8ad9d;
}
section {
display: flex;
align-items: center;
justify-content: space-around;
gap: 5rem;
min-height: 500px;
}
img {
width: 300px;
border-radius: 10px;
margin-top: 50px;
transition: 0.8s ease;
}
img:hover {
margin-bottom: 20px;
box-shadow: 12px 12px #07072c;
}
.darkestPeach {
background-color: #f08080;
font-family: "Poppins", sans-serif;
color: antiquewhite;
}
.darkPeach {
background-color: #f4978e;
}
.Peach {
background-color: #f8ad9d;
display: grid;
grid-template-columns: 40% auto;
}
.lightPeach {
background-color: #f7dba7;
color: White;
font-family: "Poppins", sans-serif;
}
.awards:hover {
margin-bottom: 20px;
box-shadow: 12px 12px wheat;
}
.gray {
font-family: "Poppins", sans-serif;
}
.whitePeach {
background-color: antiquewhite;
display: grid;
grid-template-columns: 50% 50%;
font-family: "Poppins", sans-serif;
word-wrap: break-word;
justify-content: space-between;
align-content: center;
}
.hidden {
opacity: 0;
transition: all 1s;
filter: opacity(0);
transform: translateX(-100%);
}
.show {
opacity: 1;
filter: opacity(100%);
transform: translateX(0);
}
@media (prefers-reduced-motion) {
.hidden {
transition: none;
}
}
span {
font-family: "Lobster", cursive;
}
.final {
gap: 1rem;
font-family: "Dancing Script", cursive;
background-image: url("https://media.discordapp.net/attachments/701125768675065917/1030317951141818398/2022-10-13_10.png?width=1246&height=701");
}
.move {
margin-right: 1000px;
}
Note: I got the hex colors from coolors.co, it's a nice place to find hex colors!
Scroll Animation
For the scroll Animation i used IntersectionObserver
wich is used to observe changes in a targeted element(you can learn more here). I used it so when an element of a section intersects and is now observed the animation will start. First i made a const
variable that stores all the elements with the class hidden on it by using document.querySelectorAll()
. I then made another const
variable but this one has the IntersectionObserver()
. Inside the Intersection Observer it has the property called entries
wich means it can observe multiple entries. Due to this i needed to use a for loop over them so then i can run a conditonal check to find out if the entry is intersecting the viewport or not. If
it's intersecting the show class will be added to that element but for anything else
that new class will be removed. This is so if the element isn't intersecting the viewport anymore the animation will go back making the animation run again whenever it in the viewport again. Finally i told the observer to observe each hidden class element.
const hiddenElements = document.querySelectorAll(".hidden");
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
console.log(entry);
if (entry.isIntersecting) {
entry.target.classList.add('show');
}
else {
entry.target.classList.remove('show');
}
});
})
hiddenElements.forEach((el) => observer.observe(el));
Top comments (0)