ویژگی تصویر

افکت بارش برف با CSS — راهنمای جامع و عملی

  /  CSS   /  افکت بارش برف با CSS
بنر تبلیغاتی الف

افکت بارش برف یکی از جذاب‌ترین جلوه‌های بصری برای وب‌سایت‌هاست که می‌تواند فضای فصلی یا جوی خاصی بسازد. در این مقاله به روش‌های مختلف ساخت “افکت بارش برف با CSS” می‌پردازیم: از راهکارهای فقط با CSS تا نسخه‌های بهینه شده با JavaScript برای کنترل تصادفی، همچنین نکات دسترسی و بهینه‌سازی عملکرد.

چرا از CSS برای بارش برف استفاده کنیم؟

  • سبُک و بدون وابستگی به لایبرری‌های خارجی
  • قابلیت استفاده هم‌زمان با انیمیشن‌های GPU (با transform)
  • قابلیت ترکیب با تصاویر پس‌زمینه و فیلترها

اصول اولیه افکت بارش برف

ایده کلی: چند عنصر (یا سایهٔ چند نقطه) که از بالا به پایین حرکت می‌کنند، با اندازه و سرعت و تاخیر‌های مختلف تا حس عمق ایجاد شود. برای عملکرد بهتر از transform: translateY یا translate3d استفاده کنید تا رندر روی GPU انجام شود.

نمونه ساده — CSS فقط

<div class="snow">
  <span class="flake"></span>
  <span class="flake"></span>
  <span class="flake"></span>
  <!-- تکرار برای تعداد بیشتر یا تولید با JS -->
</div>

.snow {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: hidden;
  z-index: 9999;
}

.flake {
  position: absolute;
  top: -10vh;
  width: 8px;
  height: 8px;
  background: white;
  border-radius: 50%;
  opacity: 0.9;
  transform: translate3d(0,0,0);
  animation-name: fall;
  animation-duration: 10s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/* نمونه keyframes */@keyframes fall {
  to {
    transform: translate3d(100px, 110vh, 0) rotate(360deg);
  }
}

/* با nth-child می‌توان تاخیر و اندازه را متفاوت کرد */.flake:nth-child(1) { left: 10%; animation-duration: 8s; opacity: 0.8; width:6px; height:6px; }
.flake:nth-child(2) { left: 30%; animation-duration: 12s; opacity: 0.95; width:10px; height:10px; animation-duration:10s; }

توضیح: این نمونه پایه‌ای از عناصر <span> است که به‌صورت مطلق قرار می‌گیرند و با keyframes از بالا به پایین حرکت می‌کنند. با nth-child می‌توان به هر عنصر تاخیر، سرعت و اندازه متفاوت داد تا ریزش طبیعی‌تر دیده شود. برای تعداد زیادتر، می‌توان عناصر را دستی گذاشت یا با JS تولید کرد.

نسخه بهبود یافته با JavaScript (تولید دینامیک)

<div class="snow"></div>

<style>
.snow { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index:9999; }
.snow .flake {
  position: absolute;
  top: -10vh;
  background: white;
  border-radius: 50%;
  opacity: 0.9;
  transform: translate3d(0,0,0);
  will-change: transform, opacity;
  animation-name: fall;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes fall {
  to { transform: translate3d(var(--x), 110vh, 0) rotate(var(--rot)); }
}
</style>

<script>
const container = document.querySelector('.snow');
const flakes = 80; // تعداد گلوله‌های برف
for(let i=0;i<flakes;i++){
  const f = document.createElement('div');
  f.className = 'flake';
  const size = Math.random()*8 + 4; // اندازه بین 4 تا 12px
  const left = Math.random()*100; // درصد از عرض
  const drift = (Math.random()*200 - 100).toFixed(0) + 'px'; // لغزش افقی تصادفی
  const dur = (Math.random()*10 + 6).toFixed(2) + 's'; // زمان بین 6 تا 16s
  const delay = (Math.random()*-20).toFixed(2) + 's'; // منفی تاخیر برای پراکندگی
  const rot = (Math.random()*720 - 360).toFixed(0) + 'deg';
  f.style.width = size + 'px';
  f.style.height = size + 'px';
  f.style.left = left + '%';
  f.style.setProperty('--x', drift);
  f.style.setProperty('--rot', rot);
  f.style.animationDuration = dur;
  f.style.animationDelay = delay;
  f.style.opacity = (0.6 + Math.random()*0.4).toFixed(2);
  container.appendChild(f);
}
</script>

توضیح: این کد با JavaScript تعدادی عنصر .flake می‌سازد و با مقداردهی CSS متغیرها (CSS variables) رفتار هر دانه را تصادفی می‌کند. animation-duration و animation-delay برای هر دانه متفاوت است؛ transform با translate3d و will-change برای عملکرد بهتر استفاده شده‌اند.

نکات بهینه‌سازی و دسترسی

  • برای کاهش مصرف CPU/GPU از تعداد متعادل دانه‌ها استفاده کنید (مثلاً 50–150 بسته به هدف).
  • از translate3d/transform استفاده کنید تا انیمیشن توسط GPU پردازش شود.
  • will-change را با دقت اضافه کنید و پس از استفاده آن را حذف کنید—استفاده بیش از حد ممکن است حافظه را اشغال کند.
  • پشتیبانی از media query برای کاربران با کاهش حرکت: @media (prefers-reduced-motion: reduce) { .flake { animation: none; } }

جدول پروپرتی‌های مفید برای افکت برف

پروپرتیتوضیح
transform: translate3d()انیمیشن را به GPU می‌فرستد و روانی را افزایش می‌دهد.
will-changeبه مرورگر اطلاع می‌دهد کدام خصوصیات تغییر خواهند کرد.
animation-delayبرای پراکندگی زمان شروع و طبیعی‌تر شدن حرکت.
opacity / filter(blur)برای ایجاد عمق و افکت مه آلود.

پیشنهادات و بهینه‌سازی‌های بیشتر

  • برای افکت عمق، چند لایه از عناصر با سرعت‌ها و سایزهای متفاوت بسازید (لایهٔ عقب کندتر و تارتر).
  • از تصاویر SVG یا الگوهای background برای دانه‌های پیچیده‌تر استفاده کنید.
  • اگر نیاز به تعامل یا توقف افکت دارید، کنترل‌ها را با JS بسازید (مثلاً دکمهٔ روشن/خاموش).

نمونهٔ رعایت دسترسی (reduced motion)

@media (prefers-reduced-motion: reduce) {
  .flake { animation: none !important; opacity: 0.6; }
}

توضیح: این قانون برای کاربرانی که حرکت زیاد در صفحه باعث ناراحتی می‌شود، انیمیشن را خاموش می‌کند و به تجربهٔ دسترس‌پذیر کمک می‌کند.

نتیجه‌گیری کوتاه

افکت بارش برف با CSS می‌تواند از بسیار ساده تا پیشرفته و قابل تنظیم با JavaScript پیاده‌سازی شود. کلیدهای موفقیت: استفاده از transform برای عملکرد بهتر، پراکندگی تصادفی برای طبیعی بودن، و رعایت دسترسی با prefers-reduced-motion. با ترکیب این تکنیک‌ها می‌توانید جلوه‌ای زیبا، سبک و قابل کنترل بسازید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: