ویژگی تصویر

ساخت سیستم امتیازدهی ستاره ای با CSS

  /  CSS   /  ساخت سیستم امتیازدهی ستاره ای با CSS
بنر تبلیغاتی الف

سیستم امتیازدهی ستاره‌ای یکی از پرکاربردترین الگوها برای نمایش بازخورد کاربران در وب‌سایت‌ها و اپلیکیشن‌هاست. این نوع نمایش بصری، تصمیم‌گیری کاربران را سریع‌تر می‌کند و می‌تواند تأثیر چشمگیری روی نرخ تبدیل و اعتمادسازی داشته باشد. در این مقاله به صورت عملی و مرحله‌به‌مرحله نشان می‌دهیم چگونه یک سیستم امتیازدهی ستاره‌ای با CSS بسازید، دسترس‌پذیر نگه‌دارید و نکات بهینه‌سازی را بیان می‌کنیم.

الگوی پایه — HTML و CSS ساده با ورودی‌های رادیویی

برای داشتن تعامل (کلیک و انتخاب)، بهترین روش استفاده از المان‌های فرم مثل input[type="radio"] است. با CSS می‌توان همه چیز را بدون JavaScript پیاده‌سازی کرد.

<div class="star-rating" role="radiogroup" aria-label="امتیاز">
  <input type="radio" id="star5" name="rating" value="5">
  <label for="star5" title="5 stars">★</label>
  <input type="radio" id="star4" name="rating" value="4">
  <label for="star4" title="4 stars">★</label>
  <input type="radio" id="star3" name="rating" value="3">
  <label for="star3" title="3 stars">★</label>
  <input type="radio" id="star2" name="rating" value="2">
  <label for="star2" title="2 stars">★</label>
  <input type="radio" id="star1" name="rating" value="1">
  <label for="star1" title="1 star">★</label>
</div>

در این کد، ما از ستارهٔ یونیکد برای نمایش استفاده کرده‌ایم. برای اینکه ترتیب انتخاب درست کار کند (وقتی یک ستاره انتخاب می‌شود همهٔ ستاره‌های قبل آن نیز رنگی شوند)، معمولاً از CSS با flex-direction: row-reverse یا انتخابگرهای خواهر استفاده می‌کنیم.

.star-rating {
  display: inline-flex;
  flex-direction: row-reverse;
  font-size: 2rem;
}
.star-rating input { display: none; }
.star-rating label {
  cursor: pointer;
  color: #ccc;
  transition: color .2s;
}
.star-rating label:hover,
.star-rating label:hover ~ label,
.star-rating input:checked ~ label {
  color: #f5b301; /* رنگ ستاره‌های فعال */}

این CSS رفتار hover و checked را کنترل می‌کند. ترتیب معکوس باعث می‌شود که انتخاب یک input (مثلاً ستاره سوم) با استفاده از گزارهٔ ~ تمام لیبل‌های بعدی را تحت تأثیر قرار دهد.

دسترسی و کیبورد (+ ARIA)

برای دسترس‌پذیر کردن این سیستم، باید مطمئن شویم که کاربران صفحه‌خوان و کاربرانی که از کیبورد استفاده می‌کنند می‌توانند امتیاز دهند.

  • استفاده از role="radiogroup" برای گروه.
  • اضافه کردن aria-label یا aria-labelledby برای توضیح.
  • قابل فوکوس بودن لیبل‌ها با CSS: label { outline: none; } و برای کیبورد تعامل با input ها کافی است.

نمونهٔ ارتقا یافته با فوکوس قابل مشاهده

.star-rating label:focus {
  outline: 2px solid #ffa;
  outline-offset: 2px;
}
.star-rating input:focus + label { /* وقتی input فوکوس دارد، لیبل بعد از آن قابل دیدن باشد */ }

برای اینکه کاربران بتوانند با فلش‌ها یا Tab بین گزینه‌ها حرکت کنند، مرورگر به‌صورت پیش‌فرض این رفتار را برای inputهای نوع رادیو فراهم می‌کند. فقط مطمئن شوید ورودی‌ها نمایش داده نشده ولی در دسترس هستند (ما با display:none پوشانده‌ایم؛ برای دسترسی بهتر می‌توان از تکنیک‌های visually-hidden استفاده کرد).

نمایش مقدار عددی زنده با JavaScript (اختیاری)

برای تجربه کاربری بهتر، اغلب لازم است که مقدار انتخاب‌شده به صورت عددی کنار ستاره‌ها نمایش داده شود. این کار را می‌توان با اندکی JavaScript انجام داد.

const rating = document.querySelector('.star-rating');
const output = document.getElementById('rating-value');

rating.addEventListener('change', (e) => {
  if (e.target.name === 'rating') {
    output.textContent = e.target.value;
  }
});

در این اسکریپت ساده، به رویداد change گوش می‌دهیم و وقتی یکی از inputها تغییر می‌کند، مقدار را در یک المان خروجی نمایش می‌دهیم. این روش سبک و مناسب برای فرم‌ها است.

ستاره‌های نیمه یا نمایش اعشاری (فراکشنال) با CSS

اگر بخواهید میانگین امتیاز را به صورت اعشاری نشان دهید (مثلاً 4.3)، می‌توانید از پس‌زمینهٔ خطی یا ماسک SVG استفاده کنید. اینجا یک نمونهٔ ساده با CSS variables و gradient داریم.

.avg-stars {
  --percent: 86%; /* مقدار درصد قابل تغییر است (مثال: 4.3 از 5 = 86%) */  display: inline-block;
  font-size: 2rem;
  background: linear-gradient(90deg, #f5b301 var(--percent), #ccc var(--percent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
}
.avg-stars::before {
  content: '★★★★★';
  -webkit-background-clip: text;
  background-clip: text;
}

در این روش از گرادیان و clip استفاده می‌کنیم تا تنها درصد مشخصی از متن ستاره‌ای رنگی شود. این راه مناسب نمایش فقط خواندنی است و با CSS خالص برای حالت‌های تعاملی ترکیب نمی‌شود مگر با پیچیدگی بیشتر.

بهینه‌سازی، نکات عملی و موارد استفاده

  • برای فرم‌های ارسال امتیاز، Validation سمت سرور داشته باشید تا امتیاز جعلی ثبت نشود.
  • برای نمایش میانگین از روش CSS fractional یا رسم SVG استفاده کنید تا ظاهری دقیق و زیبا داشته باشید.
  • در صفحات موبایل سایز قابل کلیک ستاره‌ها را افزایش دهید (minimum touch target حداقل 44x44px).
  • برای SEO، می‌توانید میانگین امتیاز را با Schema.org (aggregateRating) در JSON-LD قرار دهید تا موتورهای جستجو امتیاز را شناسایی کنند.

جدول مقایسهٔ روش‌ها

روشمزایامعایب
CSS-only (radio + label)بدون JS، ساده، دسترس‌پذیرمحدود در نمایش اعشاری
CSS fractional (gradient)نمایش دقیق اعشاری، زیبافقط خواندنی معمولاً، پیچیدگی برای تعامل
SVG + JSقابل پیکربندی کامل، انیمیشن، fractional، تعامل پیچیدهنیاز به JS و پیچیدگی بیشتر

جمع‌بندی و نکات پایانی

سیستم امتیازدهی ستاره‌ای با CSS یک راه سریع و موثر برای جمع‌آوری و نمایش بازخورد است. با ترکیب inputهای رادیویی و لیبل‌ها می‌توان بدون جاوااسکریپت تجربهٔ تعاملی خوبی ساخت. برای نمایش میانگین‌های اعشاری، از تکنیک‌های گرادیان یا SVG استفاده کنید. همیشه دسترس‌پذیری، تجربه کاربری موبایل و اعتبارسنجی سمت سرور را در نظر داشته باشید.

اگر دوست دارید، می‌توانم نمونهٔ کامل پروژه با SVG و انیمیشن و JSON-LD آماده کنم یا نسخهٔ React-friendly این سیستم را بسازم.

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

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