Atmosphere✨ Premium

Snow Fall

Unicode snowflakes driven by CSS keyframes fall in a night-sky loop — JS recycles each flake on animationend for a continuous stream without canvas or rAF.

JSWinter

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Atmosphere has 57 effects, including 10 free. Explore the category →

3 usage examples

Hero / Landing — Winter sale e-commerce banner — Snow Fall example 1

① Hero / Landing — Winter sale e-commerce banner

WhenAn online store activates its seasonal homepage: January sales, Christmas campaign, or a snowy Black Friday.
WhyCSS animations run on the compositor thread and do not affect the hero's LCP — snow appears without touching the main thread or adding to the critical rendering budget.
Settings20 initial flakes, animation-duration 6–10 s for a slow romantic fall, font-size max 20 px, translateY matched to actual hero height, background replaced by a snowy landscape in background-image.
Seasonal section — Ski resort landing page — Snow Fall example 2

② Seasonal section — Ski resort landing page

WhenA winter booking page, outdoor shop, or ski-resort site wants to dress its hero section with an immersive full-width snow atmosphere.
WhySnow covers the entire background (night-sky gradient or mountain <code>background-image</code>), letting the effect show its full scale rather than being squeezed into a small widget. Flakes fall the full height of the block without ever being cropped.
Settings25 flakes, animation-duration 6–10 s for a slow romantic fall, translateY matched to block height (360 px or 100 vh), background replaced by a mountain gradient (#0e2038 → #06101a) or a landscape image.
Advent calendar — Daily reveal screen — Snow Fall example 3

③ Advent calendar — Daily reveal screen

WhenAn e-commerce or editorial site launches an interactive Advent calendar: every day a full-frame screen opens with snow in the background to reveal the deal or surprise of the moment.
WhyFull-frame background snow creates a festive and immersive atmosphere — that is where this effect has maximum impact. The semi-transparent decorative flakes do not obscure the central content, and the CSS animation does not drain battery on mobile.
Settings30 flakes for festive density, animation-duration 4–7 s (slightly faster fall = excitement of discovery), font-size 12–26 px, opacity capped at 0.7 so the central content stays legible.

How it works

Each snowflake is a div.snow2-flake holding a Unicode character (❅, ✼, ❆…). The fall is entirely driven by @keyframes snow2Fall: translateY(-20px) rotate(0deg)translateY(300px) rotate(360deg) as linear infinite. No requestAnimationFrame, no canvas — the browser's CSS engine handles every frame on the compositor thread.

createSnowflake() builds an element with randomised properties: left 0–100 %, font-size 10–24 px, opacity 0.4–1.0, animation-duration 4–8 s, animation-delay 0–2 s. An animationend listener removes the finished flake and immediately creates a new one — the stream is continuous and memory stays flat (one out, one in).

The .snow2-container sits at position: absolute; inset: 0 with a night-sky linear gradient (#1e3a5f → #0f1c2e) and overflow: hidden clipping flakes at the edges. A text-shadow rgba(255,255,255,.5) 0 0 5px on each flake adds a soft glow suited to the dark background.

The HTML pre-seeds two flakes with inline style (pre-computed durations and delays) so the scene is never empty on first render, before the script fills the pool.

Accessibility

  • prefers-reduced-motion not handled: the source code contains no check for this media query — the CSS animation runs unconditionally, even on systems set to reduce motion. Patch manually: @media (prefers-reduced-motion: reduce) { .snow2-flake { animation: none; } }.
  • The div.snow2-flake elements contain Unicode text (❅, ✼…) without aria-hidden="true": a screen reader may announce each flake as they are created dynamically. Adding aria-hidden="true" on .snow2-container is strongly recommended.
  • The container carries neither role nor aria-label — its purely decorative purpose is invisible to assistive technology.
  • Flakes carry pointer-events: none: they do not block clicks or keyboard navigation on elements placed in overlay.
  • Contrast: the night-sky gradient provides a ratio above 7:1 for white text (#ffffff on #0f1c2e) — the flakes themselves carry no information and are purely decorative.

Browser compatibility

Requires CSS3 animations (@keyframes, animation) and the animationend event — available in all modern browsers since 2014.

Chrome 43+✓ Full
Firefox 16+✓ Full
Safari 9+✓ Full
Edge 12+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If CSS animations are disabled (battery-save mode on some devices), the two HTML-pre-seeded flakes remain visible at fixed positions — the gradient background is shown and no JS errors are thrown.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="snow2-container" id="snowContainer" aria-hidden="true">
  <span class="snow-text">Snowflakes</span>
  <!-- div.snow2-flake elements are injected dynamically by JS -->
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
snowflakes array (JS) ['❅','✼','❆','❄'] Unicode character set used for flakes in createSnowflake() — swap in any winter character or emoji to change the aesthetic.
10 + 14 * Math.random() (JS) 10–24 px Flake size range in createSnowflake() — reduce to 8 + 8 * Math.random() for fine snow, raise to 14 + 20 * Math.random() for large flakes.
4 + 4 * Math.random() + "s" (JS) 4–8 s Animation duration in createSnowflake() — increase for a slow romantic fall (7 + 5 * Math.random()), decrease for a blizzard (2 + 2 * Math.random()).
.4 + .6 * Math.random() (JS) 0.4–1.0 Opacity range in createSnowflake() — cap at .3 + .3 * Math.random() for subtle semi-transparent snow on a background image.
translateY(300px) — @keyframes snow2Fall (CSS) 300 px Fall distance in the CSS animation — match it to your container's actual height so flakes exit fully at the bottom before being recycled.
background — .snow2-container (CSS) linear-gradient(#1e3a5f, #0f1c2e) Sky gradient — set to transparent or a landscape background-image to layer the effect over an existing hero.
color — .snow2-flake (CSS) #fff Flake colour — try #b3d9f7 (glacier blue) or #e8f4ff (off-white) for a more natural look on a light background.

FAQ

Yes — the effect is 100% vanilla: native CSS animations and a micro-script (~600 bytes) with zero npm dependencies. Copy the HTML, CSS, and JS into any project (React, Vue, Svelte, Angular) targeting the right container; the effect never touches the DOM outside its own .snow2-container.
Edit translateY(300px) in @keyframes snow2Fall to match your container's height. If the container is 500 px tall, use translateY(520px) so flakes exit fully at the bottom before being recycled.
No — the delivered source code does not check this media query. Add @media (prefers-reduced-motion: reduce) { .snow2-flake { animation-play-state: paused; } } and guard createSnowflake() with if (matchMedia('(prefers-reduced-motion: reduce)').matches) return; at the top of the function to cut dynamic creation.