SnowFall effect using CSS and JavaScript Animations
5 min read
Hello there! I am Shivam,
Today I'm going to show you how to create a beautiful falling snow effect for any webpage. Wouldn't that look amazing on your blog or portfolio site during the winter holidays?
To create this effect, we will use:
• HTML - to add a container for our snowflakes
• CSS - to style and position the snowflakes
• JavaScript - to programmatically generate and GSAP to animate the snowflakes
Sound good? Open up your code editor, and let's get started! We'll be working with 3 files:
index.html
: Our HTML file with the container divstyle.css
: The CSS styles for our background and snowflakesscript.js
: The JavaScript to generate and animate the snowflakes
Go ahead and create these 3 files now so you're ready to follow along!
Setting the Scene for Snow
To create individual snowflakes that can fall, we first need to set the stage. We'll start by adding a basic HTML structure with a container div where our snowflakes will live.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Snow Fall</title>
</head>
<body>
<div id="container"></div>
<!-- Below, we are importing GSAP library for animation and attaching our JavaScript file -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js" integrity="sha512-16esztaSRplJROstbIIdwX3N97V1+pZvV33ABoG1H2OyTttBxEGkTsoIVsiP1iaTtM8b3+hu2kB6pQ4Clr5yug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="script.js"></script>
</body>
</html>
Painting a Wintry Background
Now we'll paint a wintry background for our snow to fall on. We'll use CSS to position the container div absolutely and add a winter background image.
Let's break down each part step-by-step:
The body styles
We first apply some base styles to the <body>
element to set up our scene:
body {
background-image: url(winter-landscape.jpg);
background-size: cover;
background-position: center center;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
position: relative;
}
We set a winter landscape photo as the
background-image
.Using
background-size: cover
, the image fills the entire background area.We center the image vertically and horizontally with
background-position: center center
.We hide any content overflow with
overflow: hidden
.We remove default margins and paddings with
margin: 0
andpadding: 0
.Finally, we also added a
width
,height
and aposition: relative
.
The container
We added a container to hold our snowflakes:
#container {
position: absolute;
top: 0;
left: -10%;
right: 0;
width: 110vw;
height: 110vh;
z-index: 1;
}
We position the container
position: absolute
within the<body>
.We position the top left corner using
top: 0
andleft: -10%
.Making the container
width: 110vw
andheight: 110vh
allows snowflakes to "fall offscreen".We place the container above the background with
z-index: 1
.
The snowflakes
We style each snowflake as a circle:
#container .droplet {
position: absolute;
top: -20%;
background: #fff;
border-radius: 50%;
}
We position each snowflake
position: absolute
within the container.We start each snowflake above the top with
top: -20%
.We use
background: #fff
for a white color.We make the circle shape using
border-radius: 50%
.
Crafting the Falling Snowflakes
Now for the fun part - we'll craft our snowflakes! We'll create a JavaScript function to generate snowflake elements with random styles like size, opacity, and speed.
Defining functions
We first define two functions:
randomInRange()
- Generates a random number within a range.
createDroplet()
- Creates and styles a single snowflake div.
const randomInRange = (max, min) => Math.floor(Math.random() * (max - min)) + min;
- createDroplet Function:
const createDroplet = () => {
const droplet = document.createElement("div");
droplet.className = "droplet";
This function creates a new <div>
element, assigns the class name "droplet" to it, and prepares to create the snowflake element.
const pos = randomInRange(100.5, 0);
droplet.style.left = `${pos}%`;
A random horizontal position (pos
) is generated using the randomInRange
function. The snowflake's left
position is set using this value, creating a horizontal shift within the container.
const height = randomInRange(12, 4);
droplet.style.height = droplet.style.width = `${height}px`;
Similarly, a random height (height
) for the snowflake is generated. The height and width of the snowflake element are set to this value, creating a circular shape.
const opacity = randomInRange(1, 0.8);
TweenMax.set(droplet, { opacity });
A random opacity value (opacity
) is generated. The TweenMax.set
function from the GSAP library is used to set the opacity of the snowflake element to this value, controlling its transparency.
const delay = randomInRange(10, 0);
const speed = randomInRange(17, 12);
const blurVal = randomInRange(4, 1);
const path = () => [
{ x: randomInRange(150, -150), y: randomInRange(150, -150) },
{ x: randomInRange(150, -150), y: randomInRange(150, -150) },
{ x: randomInRange(150, -150), y: randomInRange(150, -150) },
{ x: randomInRange(150, -150), y: randomInRange(150, -150) }
];
Several parameters for animating the snowflake are set: delay
, speed
, and blurVal
. Additionally, a function path
is defined, which returns an array of points. Each point contains random x
and y
coordinates to create a bezier path for the snowflake's animation.
TweenMax.to(droplet, speed, {
y: 1520,
delay,
top: -300,
filter: `blur(${blurVal}px)`,
repeat: -1,
bezier: {
type: "soft",
values: path(),
autoRotate: true
},
ease: Power1.easeInOut
});
The TweenMax.to
function animates the snowflake. It animates the snowflake's vertical (y
) position from the top to 1520 (making it fall), along the bezier path defined by the path
function. Additional properties such as delay
, top
, filter
(to add a blur effect), repeat
(to repeat the animation indefinitely), and ease
(animation easing) are configured.
return droplet;
};
Finally, the createDroplet
function returns the configured snowflake element.
Creating Snowflakes:
const dropletContainer = document.getElementById("container");
for (let i = 0; i < 200; i++) {
const droplet = createDroplet();
dropletContainer.appendChild(droplet);
}
This part of the code selects the container
element from the HTML and uses a loop to create 200 snowflakes. For each iteration, the createDroplet
function is called to generate a snowflake element, which is then appended to the container
.
Wrapping Up
In creating this beautiful snowfall animation, we've seen how HTML provides the structure, CSS brings the style, and JavaScript injects the interactivity and motion.
Thanks for reading it. I hope it was insightful. All the source code used in this article is in my GitHub repository.
If you liked the article, please post likes 👍, give it a ⭐ and share it in your circles.
Let's connect. I share content related to web development, technical writing, and Open Source on these platforms.
Thanks for reading :)