Want a festive sprinkle without heavy scripts? This pure CSS approach adds falling snow using layered PNGs and a keyframe animation. It’s lightweight, link safe (thanks to pointer-events: none), and easy to enable on Shopify and WordPress.
The core CSS
Use this exactly as is to start. You can tweak it later.
/* 1) Make the page a positioned container */
body {
position: relative;
}
/* 2) Place a non-interactive snowfall layer above the page */
body:before {
content: '';
display: block;
position: absolute;
z-index: 2; /* Adjust if it covers menus */
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none; /* Keeps links clickable */
background-image:
url('https://s3.amazonaws.com/divi-life-plugin-layouts/tutorials/snow/divi-life-snowflakes-b.png'),
url('https://s3.amazonaws.com/divi-life-plugin-layouts/tutorials/snow/divi-life-snowflakes-c.png'),
url('https://s3.amazonaws.com/divi-life-plugin-layouts/tutorials/snow/divi-life-snowflakes-a-1.png');
animation: divi-life-snow 10s linear infinite;
}
/* 3) Animation */
@keyframes divi-life-snow {
0% { background-position: 0px 0px, 0px 0px, 0px 0px; }
50% { background-position: 500px 500px, 100px 200px, -100px 150px; }
100% { background-position: 500px 1000px, 200px 400px, -100px 300px; }
}
/* Vendor-prefixed fallbacks for older browsers */
@-moz-keyframes divi-life-snow {
0% { background-position: 0px 0px, 0px 0px, 0px 0px; }
50% { background-position: 500px 500px, 100px 200px, -100px 150px; }
100% { background-position: 500px 1000px, 200px 400px, -100px 300px; }
}
@-webkit-keyframes divi-life-snow {
0% { background-position: 0px 0px, 0px 0px, 0px 0px; }
50% { background-position: 500px 500px, 100px 200px, -100px 150px; }
100% { background-position: 500px 1000px, 200px 400px, -100px 300px; }
}
@-ms-keyframes divi-life-snow {
0% { background-position: 0px 0px, 0px 0px, 0px 0px; }
50% { background-position: 500px 500px, 100px 200px, -100px 150px; }
100% { background-position: 500px 1000px, 200px 400px, -100px 300px; }
}
*This wonderful solution was provided by the amazing DiviLife team, you can find the original source here.
Shopify – how to add the snowfall
These steps suit Online Store 2.0 themes like Dawn. Works for most modern themes.
Option A – add to your main stylesheet
- In Shopify admin, go to Online Store → Themes, then click Edit code on your live theme.
- Open
assets/base.cssorassets/theme.css. - Paste the CSS at the bottom and save.
- View the site. If a sticky header sits under the snow, bump the header
z-indexto 3 or higher, or lower the snow’s to 1.
Option B – load only on the homepage
- In Layout/theme.liquid, wrap a class on the body only when on the index template:
<body class="{% if template.name == 'index' %}snow-enabled{% endif %}">
- In base.css add:
/* Only show snow when the body has snow-enabled */
.snow-enabled { position: relative; }
.snow-enabled:before { /* paste the body:before rules here */ }
This keeps product pages clear of the effect.
Option C – host the PNGs in Shopify
- Go to Settings → Files and upload the three snowflake PNGs.
- Replace each
background-imageURL with your uploaded file URLs to avoid third-party hosting.
WordPress – how to add the snowfall
Pick the approach that fits your setup.
Option A – Additional CSS
- In your WordPress admin, go to Appearance → Customise → Additional CSS.
- Paste the CSS and publish.
- If your header is hidden beneath the snow, add:
.site-header { position: relative; z-index: 3; }
Option B – theme or child theme stylesheet
- If you use a child theme, open style.css in the child theme and paste the CSS at the end.
- Clear any caches if you run a caching plugin.
Option C – page specific in Divi or other builders
- Divi: Theme Options → Custom CSS to enable site wide. To enable on a single page only, open that page in Divi → Page Settings → Advanced → Custom CSS and paste the rules but target
.et_pb_pagebuilder_layoutinstead ofbody, or add a page-specific class to the body. - Elementor: Site Settings → Custom CSS → paste the CSS. For single-page use, give the body a class using a code snippet plugin or scope the pseudo element to
html:beforewith a guard class.
Option D – only on one page using native WordPress classes
Every WordPress page has a unique body class like .page-id-123:
.page-id-123 { position: relative; }
.page-id-123:before { /* paste the body:before rules here */ }
Make it accessible
@media (prefers-reduced-motion: reduce) {
body:before,
.snow-enabled:before,
.page-id-123:before {
animation: none !important;
}
}
Customise the effect
Speed
Change animation: divi-life-snow 10s linear infinite; — lower is faster. Example: 8s feels more lively.
Density
Use larger PNGs or add another background layer:
background-image:
url('flake-1.png'),
url('flake-2.png'),
url('flake-3.png'),
url('flake-4.png'); /* new layer */
Depth feel
Add different movement amounts per layer — change the background-position values in the keyframes. Higher Y values make flakes travel further.
Stacking
If dropdowns appear under the snow, set the menu container to a higher z-index or lower the snow layer:
body:before { z-index: 1; }
.site-header, .header-wrapper { position: relative; z-index: 3; }
Scope and scheduling
Only want snow in December? Add a class with Liquid or JavaScript in that month.
Shopify – Liquid date check in theme.liquid:
{% assign month = 'now' | date: '%m' %}
<body class="{% if month == '12' %}snow-enabled{% endif %}">
WordPress – tiny script in the footer:
<script>
(function () {
var m = new Date().getMonth(); // 0 based - 11 is December
if (m === 11) document.body.classList.add('snow-enabled');
})();
</script>
Then scope your CSS to .snow-enabled as shown earlier.
Host and performance tips
- Self-host the PNGs for faster loading.
- Compress the PNGs with TinyPNG before upload.
- Long cache headers help — Shopify and most CDNs handle this by default.
- Test on mobile. If it feels too heavy, increase animation time to
12sto reduce perceived load.
Remove or pause the effect
- Delete the CSS or comment out the
animationline. - If you used
.snow-enabled, remove that class to switch it off.
Quick checklist
- Paste CSS in the right place (Shopify
base.cssor WordPress Additional CSS). - Ensure the header sits above the snow if needed — adjust
z-index. - Respect reduced motion preference.
- Scope to specific pages if you don’t want global snow.
- Host assets locally for speed.
That’s it. Copy in the CSS, refresh, and enjoy the subtle snowfall.
