ویژگی تصویر

ساخت تایمر لودینگ با CSS

  /  CSS   /  ساخت تایمر لودینگ با CSS
بنر تبلیغاتی الف

تایمرهای لودینگ (loading timer) بخش مهمی از تجربه کاربری در وب‌سایت‌ها و اپلیکیشن‌ها هستند. با استفاده از CSS می‌توان انیمیشن‌های ساده، کم‌حجم و قابل تنظیم ساخت که بارگذاری را نشان دهند. در این مقاله چند روش متداول، نکات دسترسی و مثال‌های عملی برای ساخت تایمر لودینگ با CSS و ترکیب محدود با JavaScript را بررسی می‌کنیم.

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

  • بارگذاری کم و عملکرد مناسب در مقایسه با تصاویر یا GIF
  • قابلیت سفارشی‌سازی با CSS variables و media queries
  • پشتیبانی خوب مرورگرها و امکان رعایت دسترسی (accessibility)

موارد استفاده رایج

  • نمایش پیشرفت بارگذاری فایل یا محتوای AJAX
  • تایمر محاوره‌های کوتاه (مثلاً قبل از ریدایرکت یا بارگذاری مجدد)
  • افزایش احساس پاسخ‌دهی در شبکه‌های کند

مثال 1 — نوار پیشرفت (Linear Progress Timer) با CSS فقط

<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
  <div class="bar"></div>
</div>

/* CSS */:root { --duration: 5s; --height: 8px; --bg: #eee; --accent: #4caf50; }
.progress {
  width: 100%;
  background: var(--bg);
  border-radius: 4px;
  overflow: hidden;
  height: var(--height);
}
.bar {
  width: 0%;
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #81c784);
  animation: fill var(--duration) linear forwards;
}
@keyframes fill {
  from { width: 0%; }
  to { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .bar { animation: none; width: 100%; }
}

توضیح: این مثال یک نوار پیشرفت ساده است که با تعریف متغیر CSS (–duration) می‌توانید مدت زمان تایمر را تنظیم کنید. انیمیشن keyframes از 0% تا 100% عرض را پر می‌کند. همچنین از prefers-reduced-motion برای احترام به تنظیمات کاربر استفاده شده است. برای دسترسی (accessibility) از role=”progressbar” و aria-valu* استفاده شده — اما مقدار aria-valuenow باید با JavaScript به‌روز شود اگر نیاز به گزارش دقیق باشد.

بهبود — به‌روزرسانی aria-valuenow با جاوااسکریپت

// simple JS to update aria-valuenow periodically
const progress = document.querySelector('.progress');
const bar = document.querySelector('.bar');
const duration = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--duration')) * 1000;
let start = performance.now();
function animate(now) {
  let elapsed = now - start;
  let pct = Math.min(100, (elapsed / duration) * 100);
  bar.style.width = pct + '%';
  progress.setAttribute('aria-valuenow', Math.round(pct));
  if (pct < 100) requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

توضیح: چون مقدار aria-valuenow باید عددی باشد، با requestAnimationFrame مقدار را برحسب زمان محاسبه و به‌روزرسانی می‌کنیم. این روش ترکیب ساده‌ای از CSS و JS است تا هم جلوه‌ی بصری با CSS داشته باشیم و هم اطلاعات دسترسی دقیق را منتقل کنیم.

مثال 2 — تایمر دایره‌ای (Circular Timer) با SVG و CSS

<svg class="circle-timer" viewBox="0 0 100 100" width="120" height="120" aria-hidden="false" role="img">
  <circle cx="50" cy="50" r="45" class="track" />
  <circle cx="50" cy="50" r="45" class="progress" />
</svg>

/* CSS */.circle-timer { transform: rotate(-90deg); }
.circle-timer .track {
  fill: none;
  stroke: #eee;
  stroke-width: 10;
}
.circle-timer .progress {
  fill: none;
  stroke: #2196f3;
  stroke-width: 10;
  stroke-dasharray: 282.743; /* 2πr */  stroke-dashoffset: 282.743;
  animation: dash var(--duration) linear forwards;
}
@keyframes dash {
  to { stroke-dashoffset: 0; }
}

توضیح: در این مثال از SVG برای رسم دایره استفاده شده است. با stroke-dasharray و stroke-dashoffset انیمیشن از 0 تا 100 درصد مسیر دایره را پر می‌کند. گردش دایره با rotate(-90deg) طوری تنظیم شده که شروع از بالا باشد. برای تنظیم زمان دوباره از متغیر –duration استفاده کنید.

مثال 3 — تایمر شمارنده عددی با کمک یک اسکریپت کوچک

<div class="countdown" role="timer" aria-live="polite">
  <span class="number">5</span>s
</div>

/* CSS */.countdown { font-size: 24px; font-weight: 600; }
.number { display:inline-block; width:24px; text-align:center; }

/* JS */const total = 5;
const number = document.querySelector('.number');
let current = total;
number.textContent = current;
const interval = setInterval(() => {
  current--;
  number.textContent = current;
  if (current <= 0) {
    clearInterval(interval);
    // action after timer ends
  }
}, 1000);

توضیح: برای نمایش عددی شمارش معکوس به‌سادگی از setInterval استفاده شده. CSS فقط شکل و اندازه متن را کنترل می‌کند؛ منطق زمان‌شماری در JS است تا عدد دقیق نمایش داده شود. برای سازگاری با تایمر بصری می‌توان این JS را با انیمیشن‌های CSS ترکیب کرد.

نکات حرفه‌ای و دسترسی

  • همواره prefers-reduced-motion را رعایت کنید تا برای کاربران دارای حساسیت حرکتی مشکلی پیش نیاید.
  • برای پیشرفت دقیق، aria-valuenow را با JS به‌روزرسانی کنید یا از role=”timer” و aria-live برای اعلان پایان استفاده کنید.
  • استفاده از CSS variables باعث می‌شود مدت زمان و رنگ‌ها به راحتی قابل تغییر باشند.
  • در بارهای طولانی، بهتر است یک متن جایگزین یا امتیازی برای قطع/ادامه قرار دهید.

مقایسه سریع روش‌ها

روشمزیتمعایب
CSS-only (نوار)کم‌حجم، سادهعدم نمایش عدد دقیق برای دسترسی
SVG دایره‌ایزیبا، قابل تغییر با strokeنیاز به محاسبه dash برای اندازه‌های متفاوت
CSS + JSدقیق و قابل گزارش‌دهی (aria)کمی پیچیده‌تر اما انعطاف‌پذیر

خلاصه و توصیه نهایی

اگر نیاز فقط نمایش بصری کوتاه دارید، از CSS-only استفاده کنید. برای دسترسی بهتر و گزارش دقیق وضعیت، CSS را با یک اسکریپت کوچک ترکیب کنید تا aria-valuenow و متن‌های اعلامی را به‌روز کند. همیشه تنظیمات کاربر مثل prefers-reduced-motion را مد نظر داشته باشید و از CSS variables برای پیکربندی آسان استفاده کنید.

در عمل، ترکیب یک نوار یا دایره زیبا با یک شمارنده عددی ساده بهترین تجربه را ارائه می‌دهد: زیبا، عملکردی و قابل دسترسی.

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

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