عنوان:

‫نمایش اعداد انگلیسی به شکل فارسی در صفحات وب به کمک ویژگی استاندارد Stylistic Set 1 (ss01)


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۸/۱۹ ۱۱:۴۰
آدرس: www.dntips.ir
در دنیای توسعه وب و اپلیکیشن‌های فارسی‌زبان، نمایش صحیح اعداد، یکی از چالش‌های رایج است. بسیاری از توسعه‌دهندگان با این مسئله روبرو می‌شوند که اعداد انگلیسی (لاتین) مانند 0123456789 به‌جای شکل فارسی‌شان (۰۱۲۳۴۵۶۷۸۹) نمایش داده می‌شوند. این مشکل نه تنها ظاهر رابط کاربری را تحت تأثیر قرار می‌دهد، بلکه می‌تواند تجربه کاربری را برای مخاطبان فارسی‌زبان نامناسب کند. در این مقاله، به بررسی این مسئله می‌پردازیم و راه‌حل‌های قدیمی و جدید را مقایسه می‌کنیم. هدف ما ارائه یک رویکرد حرفه‌ای و کارآمد است که بر پایه استانداردهای مدرن وب بنا شده باشد. اگر شما یک توسعه‌دهنده فرانت‌اند هستید، این مقاله به شما کمک می‌کند تا از اشتباهات رایج اجتناب کنید و کدهای تمیزتری بنویسید.

توضیح مسئله
مسئله اصلی از تفاوت بین کاراکترهای اعداد در یونیکد ناشی می‌شود. اعداد انگلیسی (ASCII digits) با کدهای U+0030 تا U+0039 ذخیره می‌شوند، در حالی که اعداد فارسی (Persian digits) از U+06F0 تا U+06F9 استفاده می‌کنند. در محیط‌های RTL (راست به چپ) مانند صفحات فارسی، اگر فونت مناسبی انتخاب نشود، اعداد به شکل انگلیسی نمایش داده می‌شوند که می‌تواند خوانایی را کاهش دهد – مثلاً عدد ۴ به‌جای ۴ فارسی که شکل متفاوتی دارد.
این مشکل اغلب در مرورگرهای مدرن مانند کروم و فایرفاکس بروز می‌کند، به ویژه وقتی اعداد از منابع خارجی (مانند دیتابیس یا API) به صورت انگلیسی وارد می‌شوند. علاوه بر این، استفاده از اعداد عربی (مانند ١٢٣٤٥٦٧٨٩٠) نیز کمکی نمی‌کند، زیرا برخی glyphها (شکل‌های گرافیکی) مانند ۴، ۵، ۶ و ۰ در عربی با فارسی متفاوت هستند. این مسئله نه تنها در وب، بلکه در اپ‌های دسکتاپ یا موبایل هم دیده می‌شود و می‌تواند به مشکلات سئو (به دلیل تغییر کاراکترها) یا عملکرد (به دلیل پردازش اضافی) منجر شود.

راه‌حل قدیمی
در گذشته، توسعه‌دهندگان اغلب به روش‌های دستی و غیراستاندارد متوسل می‌شدند. یکی از رایج‌ترین رویکردها، استفاده مستقیم از کاراکترهای فارسی در کد بود؛ مثلاً نوشتن ۰۱۲۳۴۵۶۷۸۹ به جای 0123456789. این روش ساده به نظر می‌رسد، اما مشکلات زیادی ایجاد می‌کند: اگر داده‌ها پویا باشند (مانند اعداد از API)، باید همیشه آنها را تبدیل کنید.
رویکرد دیگر، نوشتن یک تابع جاوااسکریپت یا CSS برای تبدیل کاراکترها بود. مثلاً تابعی مانند این:
function toPersianDigits(num) {
  return num.toString().replace(/\d/g, d => '۰۱۲۳۴۵۶۷۸۹'[d]);
}
این تابع هر رقم انگلیسی را به معادل فارسی‌اش تبدیل می‌کند. اما این روش معایبی دارد:
  • عملکرد پایین: برای داده‌های بزرگ، پردازش اضافی زمان‌بر است.
  • مشکلات سازگاری: در جستجو یا کپی-پیست، کاراکترهای فارسی ممکن است درست کار نکنند (مثلاً در فیلدهای ورودی یا اکسل).
  • پیچیدگی نگهداری: اگر نیاز به اعداد تبولار (هم‌عرض) یا ویژگی‌های دیگر باشد، کد پیچیده‌تر می‌شود.
  • علاوه بر این، این روش با استانداردهای وب مدرن همخوانی ندارد و می‌تواند به مشکلات امنیتی (مانند تزریق کد در تبدیل‌ها) منجر شود.

راه‌حل جدید
رویکرد مدرن، استفاده از ویژگی‌های OpenType در فونت‌هاست. فونت وزیرمتن (Vazirmatn) یکی از بهترین گزینه‌هاست که به طور خاص برای زبان فارسی طراحی شده و از Stylistic Set 1 (ss01) پشتیبانی می‌کند. این ویژگی، glyphهای اعداد انگلیسی را بدون تغییر کاراکترها، به شکل فارسی نمایش می‌دهد. مزیت اصلی: داده‌ها همچنان انگلیسی می‌مانند (برای سئو و پردازش بهتر)، اما ظاهر فارسی دارند.
با این حال، اگر فونت را از Google Fonts لود کنید، ss01 کار نمی‌کند زیرا API گوگل فقط زیرمجموعه‌ای از ویژگی‌های OpenType را پشتیبانی می‌کند. راه‌حل: فونت را محلی host کنید. ابتدا فونت را از GitHub پروژه (https://github.com/rastikerdar/vazirmatn) دانلود کنید و سپس با CSS زیر استفاده کنید:
@font-face {
  font-family: 'Vazirmatn';
  src: url('fonts/Vazirmatn-Regular.woff2') format('woff2'),
       url('fonts/Vazirmatn-Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}

html {
  font-family: 'Vazirmatn', system-ui;
  font-feature-settings: "ss01";
  direction: rtl; /* برای پشتیبانی بهتر RTL */
}
در این کد، @font-face فونت را تعریف می‌کند و font-feature-settings: "ss01"; ویژگی را فعال می‌کند. برای تست، اعداد انگلیسی مانند 0123456789 باید به شکل ۰۱۲۳۴۵۶۷۸۹ نمایش داده شوند.
اگر نمی‌خواهید از ss01 استفاده کنید، از نسخه‌های آماده در پوشه misc/Farsi-Digits ریپازیتوری استفاده کنید – اینها اعداد را مستقیماً فارسی می‌کنند بدون نیاز به ویژگی اضافی.

یک مثال کامل (با شرط کپی فایل‌های اصلی قلم، در پوشه‌ی محلی fonts):
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <!--<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Vazirmatn">-->
  <style>
	@font-face {
	  font-family: 'Vazirmatn';
	  src: url('fonts/Vazirmatn-Regular.woff2') format('woff2'),
		   url('fonts/Vazirmatn-Regular.ttf') format('truetype');
	  font-weight: normal;
	  font-style: normal;
	}

	html {
	  font-family: 'Vazirmatn', system-ui;
	  font-feature-settings: "ss01";
	}
  </style>
</head>
<body>
  <p>اعداد انگلیسی: 0123456789</p>
  <p>باید به این شکل نمایش داده بشه: ۰۱۲۳۴۵۶۷۸۹</p>
</body>
</html>

با این خروجی:

نکته اضافی: برای اعداد تبولار (که در جداول مفید است)، از "ss01", "tnum" استفاده کنید. همچنین، همیشه lang="fa" و dir="rtl" را در HTML اضافه کنید تا مرورگرها بهتر عمل کنند. این روش در مرورگرهای مدرن (کروم 57+، فایرفاکس 34+) عالی کار می‌کند، اما در نسخه‌های قدیمی ممکن است نیاز به fallback داشته باشید.

نتیجه‌گیری
نمایش اعداد فارسی با استفاده از فونت وزیرمتن و ویژگی ss01، یک راه‌حل تمیز، استاندارد و کارآمد است که از پیچیدگی‌های قدیمی اجتناب می‌کند. این رویکرد نه تنها کد را ساده نگه می‌دارد، بلکه سازگاری، عملکرد و تجربه کاربری را بهبود می‌بخشد.

نظرات

  • وحید نصیری در ۱۴۰۴/۰۸/۱۹ ۱۲:۳۶
    یک نکته‌ی تکمیلی:
    برای تشخیص سریع اینکه آیا یک فونت خاص، از ویژگی Stylistic Set 1 (ss01) پشتیبانی می‌کند، از سایت https://wakamaifondue.com استفاده کنید و در خروجی آن، دنبال ss01 یا همان «Stylistic Sets» بگردید و یا اگر فونتی ss01 نداشته باشد، مرورگر هیچ تغییری را اعمال نمی‌کند و می‌توانید با ابزارهای توسعه‌دهنده مرورگر (مثل Inspector در کروم) چک کنید که آیا ویژگی اعمال شده یا نادیده گرفته شده. همچنین ویژگی ss01 فقط در مرورگرهای مدرن پشتیبانی می‌شود؛ اما در نسخه‌های قدیمی (مثل IE زیر 10) کار نمی‌کند.