ویژگی تصویر

ساخت Animation Loader نقطه‌ای با CSS

  /  CSS   /  ساخت Animation Loader نقطه ای با CSS
بنر تبلیغاتی الف

Loader نقطه‌ای یک الگوی ساده و محبوب برای نمایش وضعیت بارگذاری است. این مقاله به شما نشان می‌دهد چگونه با CSS خالص یک loader نقطه‌ای بسازید، آن را بهینه و قابل دسترس کنید و نکات حرفه‌ای برای عملکرد بهتر ارائه می‌دهد.

چرا از loader نقطه‌ای استفاده کنیم؟

  • سبک و کم‌حجم است و با CSS به راحتی قابل پیاده‌سازی است.
  • قابل سفارشی‌سازی از نظر رنگ، اندازه و سرعت.
  • با استفاده از transform و opacity می‌توان عملکرد گرافیکی را بهینه نگه داشت.

موارد کاربرد

  • در اپلیکیشن‌های تک‌صفحه‌ای هنگام بارگذاری داده‌ها
  • در فرم‌ها هنگام ارسال اطلاعات
  • به‌عنوان placeholder یا feedback کاربر هنگام پردازش عملیات

ساخت پایه‌ای: HTML و CSS ساده

<div class="dot-loader" aria-label="loading" role="status">
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
</div>

کد HTML بالا سه نقطه می‌سازد و از role=”status” برای دسترسی بهتر استفاده می‌کند. در ادامه CSS پایه را می‌بینید.

.dot-loader {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
}

.dot {
  width: 10px;
  height: 10px;
  background: #333;
  border-radius: 50%;
  opacity: 0.2;
  transform: translateY(0);
  animation: dotPulse 1s infinite ease-in-out;
}

.dot:nth-child(1) {
  animation-delay: 0s;
}
.dot:nth-child(2) {
  animation-delay: 0.15s;
}
.dot:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes dotPulse {
  0%, 80%, 100% {
    transform: translateY(0);
    opacity: 0.2;
  }
  40% {
    transform: translateY(-8px);
    opacity: 1;
  }
}

این CSS یک انیمیشن پالس ساده ایجاد می‌کند که هر نقطه با تاخیر اجرا می‌شود تا اثر حرکت موجی شکل پدید آید. استفاده از transform و opacity باعث می‌شود مرورگر از رستر CPU کمتر استفاده و از GPU برای رسم بهره ببرد که عملکرد را بهتر می‌کند.

قابلیت تنظیم با متغیرهای CSS

برای انعطاف‌پذیری بیشتر بهتر است از CSS variables استفاده کنیم تا تغییر رنگ، اندازه و سرعت آسان باشد.

:root {
  --dot-size: 12px;
  --dot-gap: 10px;
  --dot-color: #007bff;
  --dot-duration: 0.9s;
}

.dot-loader {
  display: inline-flex;
  gap: var(--dot-gap);
  align-items: center;
}

.dot {
  width: var(--dot-size);
  height: var(--dot-size);
  background: var(--dot-color);
  border-radius: 50%;
  opacity: 0.25;
  transform: translateY(0);
  animation: dotPulse var(--dot-duration) infinite ease-in-out;
}

/* delays مشابه مثال قبل */

با این متغیرها می‌توانید در یک مکان مقادیر را تغییر دهید یا از کلاس‌های کمکی برای تم‌های مختلف استفاده کنید.

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

  • پشتیبانی از prefers-reduced-motion: برای کاربرانی که از حرکت زیاد اجتناب می‌کنند.
  • استفاده از role و aria-label برای خوانندگان صفحه‌خوان.
  • استفاده از transform و opacity به جای تغییر layout (مانند top/left) برای صرفه‌جویی در بازآرایی‌ها.
  • استفاده از will-change فقط در صورت نیاز و برای دوره کوتاه.
@media (prefers-reduced-motion: reduce) {
  .dot {
    animation: none;
    opacity: 0.6;
  }
}

/* نمونه اضافه کردن will-change در حالت فعال */.dot {
  will-change: transform, opacity;
}

کد فوق با media query مربوط به prefers-reduced-motion انیمیشن را غیرفعال می‌کند و برای کاربرانی که حرکت را نمی‌پسندند تجربه بهتری فراهم می‌آورد. will-change را صرفاً در صورت نیاز و برای مدت محدود به کار ببرید تا حافظه اضافی مصرف نشود.

نسخه پیشرفته: همگام‌سازی، رنگ متغیر و یک‌خطی بودن DOM

اگر تعداد نقاط را تغییر دهید یا بخواهید loader را پویا کنید، بهتر است از CSS فقط (بدون جاوااسکریپت) و nth-child برای استگرینگ (stagger) بهره ببرید. در ادامه یک نسخه با متغیرهای بیشتر و توضیح عملکرد می‌بینید.

.dot-loader {
  --n: 5; /* تعداد نقاط */  display: inline-grid;
  grid-auto-flow: column;
  gap: 10px;
}

.dot {
  width: 10px;
  height: 10px;
  background: linear-gradient(90deg, #ff7a18, #af002d);
  border-radius: 50%;
  opacity: 0.25;
  animation: pulse 1s calc(var(--i) * 0.12s) infinite cubic-bezier(.2,.6,.5,1);
}

.dot:nth-child(1) { --i: 0; }
.dot:nth-child(2) { --i: 1; }
.dot:nth-child(3) { --i: 2; }
.dot:nth-child(4) { --i: 3; }
.dot:nth-child(5) { --i: 4; }

@keyframes pulse {
  0%, 80%, 100% { transform: translateY(0); opacity: .25; }
  40% { transform: translateY(-10px); opacity: 1; }
}

در این الگو از CSS custom property برای تعیین اندکس هر نقطه استفاده شده و تأخیر محاسبه‌شده باعث ایجاد موجی منظم می‌شود. همین روش اجازه می‌دهد با تغییر تعداد عناصر، تاخیرها خودکار باشند (با شرط اضافه کردن کلاس‌های nth-child مناسب).

دسترس‌پذیری (Accessibility)

برای خوانندگان صفحه‌خوان از role و aria-live می‌توان استفاده کرد. اگر loader وضعیت بارگذاری را اعلام می‌کند، بهتر است متن جایگزینی هم داشته باشیم:

<div class="dot-loader" role="status" aria-live="polite">
  <span class="sr-only">Loading…</span>
  <span class="dot"></span>
  <span class="dot"></span>
  <span class="dot"></span>
</div>

در این مثال .sr-only یک کلاس CSS مخفی برای متن قابل خواندن توسط صفحه‌خوان است. aria-live به الگوریتم صفحه‌خوان می‌گوید این پیغام را با اولویت مناسب اعلام کند.

مزایا و محدودیت‌ها

مزایامحدودیت‌ها
سبک، سریع، بدون جاوااسکریپتپیچیدگی بصری محدودتر نسبت به SVG/Canvas
قابل تغییر با CSS variablesتنظیمات پیچیده‌تر ممکن است نیاز به اسکریپت داشته باشد

نتیجه‌گیری و نکات عملی

  • همیشه از transform و opacity برای انیمیشن‌های ساده استفاده کنید تا از reflow جلوگیری شود.
  • برای دسترسی، aria-label و prefers-reduced-motion را فراموش نکنید.
  • CSS variables توسعه‌پذیری و نگهداری را آسان می‌کنند.
  • در موبایل با شبکه‌های ضعیف، loader را کوتاه و ساده نگه دارید تا تجربه کاربر بهتر بماند.

با رعایت این موارد می‌توانید یک loader نقطه‌ای زیبا، سبک و قابل دسترس بسازید که در بسیاری از پروژه‌ها کاربرد دارد و به‌راحتی قابل سفارشی‌سازی و بهینه‌سازی است.

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

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