Wind Gust With Swaying Tree
A copy-paste weather & ambient component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.
Weather & AmbientHTMLCSSany framework
Copy into your project
HTML
<!-- Wind Gust With Swaying Tree (streaks fly past; the tree bends with each gust) -->
<div class="nuda-wa2-wind-gust" role="img" aria-label="Wind gusts blowing past a swaying tree">
<span class="nuda-wa2-wind-gust__streak" style="top:18%; --wg-d:0s; --wg-dur:1.3s"></span>
<span class="nuda-wa2-wind-gust__streak" style="top:36%; --wg-d:.3s; --wg-dur:1.5s"></span>
<span class="nuda-wa2-wind-gust__streak" style="top:54%; --wg-d:.6s; --wg-dur:1.7s"></span>
<span class="nuda-wa2-wind-gust__streak" style="top:72%; --wg-d:.9s; --wg-dur:1.3s"></span>
<span class="nuda-wa2-wind-gust__streak" style="top:90%; --wg-d:1.2s;--wg-dur:1.5s"></span>
<span class="nuda-wa2-wind-gust__tree">
<span class="nuda-wa2-wind-gust__trunk"></span>
<span class="nuda-wa2-wind-gust__foliage nuda-wa2-wind-gust__foliage--1"></span>
<span class="nuda-wa2-wind-gust__foliage nuda-wa2-wind-gust__foliage--2"></span>
<span class="nuda-wa2-wind-gust__foliage nuda-wa2-wind-gust__foliage--3"></span>
</span>
</div>CSS
.nuda-wa2-wind-gust {
position: relative;
width: 100%;
max-width: 220px;
height: 130px;
border-radius: 14px;
overflow: hidden;
background: linear-gradient(180deg,#12161a,#09090b);
}
.nuda-wa2-wind-gust__streak {
position: absolute;
left: -40%;
width: 60%;
height: 2px;
background: linear-gradient(90deg,transparent,rgba(228,255,84,.55),transparent);
opacity: 0;
will-change: transform,opacity;
animation: _nuda-wa2windGustStreak var(--wg-dur,1.6s) linear var(--wg-d,0s) infinite;
}
.nuda-wa2-wind-gust__tree {
position: absolute;
bottom: 0;
left: 72%;
width: 1px;
height: 1px;
transform-origin: 50% 100%;
will-change: transform;
animation: _nuda-wa2windGustSway 2.6s ease-in-out infinite;
}
.nuda-wa2-wind-gust__trunk {
position: absolute;
bottom: 0;
left: -2px;
width: 4px;
height: 40px;
background: linear-gradient(180deg,#4a3524,#2c1f15);
border-radius: 2px;
}
.nuda-wa2-wind-gust__foliage {
position: absolute;
border-radius: 50%;
background: radial-gradient(circle at 35% 30%,#3a5f2a,#22381a);
}
.nuda-wa2-wind-gust__foliage--1 {
width: 30px;
height: 26px;
bottom: 36px;
left: -15px;
}
.nuda-wa2-wind-gust__foliage--2 {
width: 22px;
height: 20px;
bottom: 48px;
left: -24px;
}
.nuda-wa2-wind-gust__foliage--3 {
width: 22px;
height: 20px;
bottom: 48px;
left: 2px;
}
@keyframes _nuda-wa2windGustSway {
0%,100% {
transform: rotate(-6deg);
}
50% {
transform: rotate(9deg);
}
}
@keyframes _nuda-wa2windGustStreak {
0% {
transform: translateX(0);
opacity: 0;
}
8% {
opacity: .8;
}
50% {
opacity: .4;
}
100% {
transform: translateX(420px);
opacity: 0;
}
}
@media (prefers-reduced-motion:reduce) {
.nuda-wa2-wind-gust__tree {
animation: none;
transform: rotate(2deg);
}
.nuda-wa2-wind-gust__streak {
animation: none;
opacity: 0;
}
}
How to use Wind Gust With Swaying Tree
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.