مقدمه

این فصل به کار با متن در صفحات وب اختصاص دارد و در اولین درس، قصد داریم در مورد موضوع مهم جهت‌گیری متن صحبت کنیم. کاراکترهای هر زبان، جهت‌گیری مشخصی دارند؛ مثلاً کاراکترهای فارسی از راست به چپ و کاراکترهای انگلیسی از چپ به راست هستند. اما از آنجایی که یک صفحه‌ی وب می‌تواند شامل کاراکترهای زبان‌های مختلف باشد، موضوع جهت‌گیری متن در HTML اهمیت ویژه‌ای پیدا می‌کند. مرورگرهای وب در مواجهه با صفحاتی که محتوای آنها از کاراکترهای دارای جهت‌گیری متفاوت تشکیل شده، الگوریتم معینی را دنبال می‌کنند که در این درس در کنار معرفی دو عنصر bdi و bdo با این الگوریتم آشنا می‌شویم.

ایزوله کردن قسمتی از متن

عنصر bdi می‌تواند بخشی از متن را که ممکن است دارای جهت‌گیری متفاوتی نسبت به متن اطرافش باشد، ایزوله کند تا از تأثیرگذاری (تأثیرپذیری) جهت‌گیری آن قسمت از متن روی (از) جهت‌گیری متن اطراف جلوگیری شود. در حقیقت، این تأثیرگذاری و تأثیرپذیری جهت‌گیری متن از متن اطراف، رفتار پیش‌فرضی است که مرورگرها به واسطه‌ی پیاده‌سازی الگوریتمی با نام اختصاری bidi انجام می‌دهند و گاهی نیاز به تغییر این رفتار پیش فرض وجود دارد. درک این موضوع و کارکرد صحیح عنصر bdi نیاز به مقدماتی دارد که در ادامه بیان می‌کنیم.

هعمانطور که می‌دانید، کاراکترهای زبان انگلیسی از چپ‌به‌راست و کاراکترهای زبان فارسی از راست‌به‌چپ نمایش داده می‌شوند. تعدادی از کاراکترها نیز جهت‌گیری مشخص و ثابتی ندارند و جهت خود را از روی کاراکترهای مجاورشان دریافت می‌کنند. به طور کلی، هر کاراکتر Unicode (مجموعه کاراکتری وب) می‌تواند دارای یکی از سه نوع جهت‌گیری زیر باشد:

  • جهت‌گیری قوی (strong): کاراکترهای دارای جهت‌گیری قوی دارای یکی از دو جهت‌گیری چپ‌به‌راست (ltr) و راست‌به‌چپ (rtl) هستند. همانطور که انتظار می‌رود، کاراکترهای لاتین دارای جهت‌گیری ltr و کاراکترهای الفبایی زبان‌هایی مانند فارسی و عربی دارای جهت‌گیری rtl هستند.
  • جهت‌گیری خنثی (neutral): کاراکترهایی مانند فاصله (space) و برخی کاراکترهای نگارشی مانند نقطه و کاما و دونقطه و غیره از نوع کاراکترهای خنثی هستند و جهت‌گیری آنها به اولین کاراکترهای قوی قبل و بعدشان بستگی دارد. به این ترتیب که اگر یک کاراکتر خنثی بین دو کاراکتر قوی با جهت‌گیری یکسان قرار گیرد، همان جهت‌گیری را دریافت می‌کند ولی اگر بین دو کاراکتر قوی با جهت‌گیری متفاوت قرار گیرد، جهت‌گیری مبنا (base direction) را دریافت می‌کند. در اسناد وب، جهت‌گیری مبنا ltr است مگر اینکه برای عنصر حاوی متن مورد نظر و یا یکی از والدهای آن عنصر، از صفت dir استفاده کرده باشیم که در این صورت، مقداری که برای این صفت فراهم کرده‌ایم، به جای مقدار پیش‌فرض ltr به عنوان جهت‌گیری مبنا برای آن متن در نظر گرفته می‌شود.
  • جهت‌گیری ضعیف (weak): کاراکترهای دارای جهت‌گیری ضعیف کاراکترهایی هستند که جهت‌گیری آنها به کاراکترهای قبلشان بستگی دارد. اعداد، بارزترین نمونه‌ی این کاراکترها هستند. به این ترتیب، اعداد اگرچه در هر صورت از چپ‌به‌راست نوشته می‌شوند اما جهت‌گیری خود عدد از روی اولین کاراکتر قوی قبل از آن عدد تعیین می‌شود.

همانطور که گفته شد، مرورگرها با تکیه بر الگوریتمی به نام Unicode bidirectional algorithm که مختصراً bidi نامیده می‌شود، جهت‌گیری دنباله‌های کاراکتری تشکیل‌دهنده‌ی متون را تعیین می‌کنند. مطابق این الگوریتم، همه‌ی کاراکترهای مجاوری که جهت‌گیری یکسانی دارند، یک گروه یا واحد مجزا در نظر گرفته می‌شوند.

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

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

جهت‌گیری چپ به راست
جهت‌گیری چپ به راست برای هر سه واحد

اما چنانچه متن مورد نظر، از روی یکی از والدهای خود مقدار rtl را برای صفت dir دریافت کند، واحدها از راست‌به‌چپ نمایش داده می‌شوند و کاراکترهای فاصله نیز چون بین دو کاراکتر قوی با جهت‌گیری متفاوت قرار دارند، جهت‌گیری مبنای خود را دریافت می‌کنند که این بار توسط یک صفت dir برابر با rtl تعیین شده است.

جهت‌گیری راست به چپ
جهت‌گیری راست به چپ برای هر سه واحد

به عنوان یک مثال دیگر، به تصویر زیر نگاه کنید. باید برایتان روشن باشد که کاراکترهای space بین کلمات فارسی دارای جهت‌گیری rtl و دو کاراکتر space دیگر دارای جهت‌گیری مبنا هستند.

جهت‌گیری کاراکترهای space
حهت‌گیری کاراکترهای space

تا اینجا همه چیز توسط الگوریتم bidi به خوبی و بدون نیاز به دخالت ما مدیریت می‌شود اما گاهی اوقات این الگوریتم به کمک ما نیاز دارد. برای درک این موضوع، مثالی ارائه می‌دهیم که ترتیب نمایش کاراکترها مطابق انتظار ما نیست و باید تغییراتی اعمال شود. فرض کنید یک علامت تعجب (!) به انتهای عبارت فارسی مثال بالا اضافه کنیم.

Copy Icon HTML
<p>
  The title is قانون پایستگی انرژی! in Persian.
</p>

با اجرای این کدها می‌بینیم که علامت تعجب در سمت راست عبارت فارسی قرار گرفته و این چیزی که ما می‌خواهیم، نیست. البته دلیل این امر کاملاً روشن است: علامت تعجب یک کاراکتر خنثی است و چون بین دو کاراکتر غیر هم‌جهت قرار دارد، جهت مبنای ltr را دریافت می‌کند. برای حل این مشکل، کافیست عبارت فارسی به علاوه‌ی علامت تعجب را درون عنصری مثل span قرار دهیم و به صفت dir آن مقدار rtl را بدهیم.

Copy Icon HTML
<p>
  The title is <span dir="rtl">قانون پایستگی انرژی!</span>in Persian.
</p>

این روش برای مواقعی مناسب است که متن مورد نظر (یا لااقل جهت‌گیری آن) از قبل مشخص باشد. اما اگر متن مورد نظر قرار باشد مثلاً توسط کاربر وارد شود و یا از روی یک دیتابیس خوانده شود و به طور کلی، جهت‌گیری آن در زمان اجرا مشخص شود، روش بالا کار نمی‌کند. در اینگونه موارد، برای جلوگیری از بروز مشکل، دو راه‌حل با نتیجه‌ی یکسان وجود دارد:

  • قرار دادن متن مورد نظر درون عنصری مانند span و اختصاص مقدار auto به صفت dir آن عنصر.
  • قرار دادن متن مورد نظر درون یک عنصر bdi بدون نیاز به صفت dir.

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

Copy Icon HTML
<ul>
  <li><span class="name">Cristiano Ronaldo</span>: 127+ goals</li>
  <li><span class="name">علی دایی</span>: 109 goals</li>
  <li><span class="name">علی دایی</span>: one hundred nine goals</li>
  <li><bdi>علی دایی</bdi>: 109</li>
  <li><span class="name">Lionel Messi</span>: 106+ goals</li>
  <li><span class="name">Sunil Chhetri</span>: 93+ goals</li>
  <li><span class="name">Mokhtar Dahari</span>: 89 goals</li>
  <li><span class="name">Ferenc Puskas</span>: 84 goals</li>
  <li><span class="name">علی مبخوت</span>: 81+ goals</li>
  <li><span class="name" dir="auto">علی مبخوت</span>: 81+ goals</li>
</ul>

اگر این کد را اجرا کنید، خواهید دید که آیتم دوم، مطابق انتظار ما نمایش داده نمی‌شود. البته دلیل این موضوع کاملاً روشن است: عدد 109 یک واحد از کاراکترهای ضعیف است و لذا جهت‌گیری آن از روی اولین کاراکتر قوی قبل از آن تعیین می‌شود که یک کاراکتر rtl است. بنابراین، 109 نیز rtl محسوب می‌شود و به همین دلیل، کاراکتر دونقطه بین دو کاراکتر rtl قرار دارد و این کاراکتر نیز rtl می‌شود. راست‌به‌چپ بودن عبارت :109 باعث می‌شود که در امتداد عبارت علی دایی نمایش داده شود. در واقع، اینجا عاملی که باعث این نمایش غیرقابل انتظار می‌شود، عدد 109 است. کما اینکه در آیتم بعدی که کاملاً مشابه آیتم دوم است اما به جای 109 از معادل آن به حروف استفاده شده، چنین مشکلی وجود ندارد. چون اینجا کاراکتر دونقطه بین دو کاراکتر قوی غیرهم‌جهت قرار دارد و لذا جهت‌گیری مبنای ltr را دریافت می‌کند. همانطور که می‌بینید، در آیتم چهارم، قرار دادن نام فوتبالیست درون عنصر bdi باعث ایزوله شدن آن و در نتیجه ممانعت از تأثیرگذاری آن روی کاراکتر دونقطه شده و لذا این کاراکتر به صورت ltr نمایش داده شده و مشکل حل شده است. اتفاق مشابهی هم در مورد آیتم مربوط به علی مبخوت فوتبالیست اماراتی رخ داده که در آیتم پایانی به روش اختصاص مقدار auto به صفت dir حل شده است.

حالا می‌توانید کارکرد دقیق عنصر bdi را درک کنید:

عنصر bdi محتوای خود را ایزوله می‌کند و اولاً مانع تأثیرگذاری آن روی جهت‌گیری متن اطراف می‌شود و ثانیاً از تآثیرگذاری متن اطراف روی محتوای خود جلوگیری می‌کند.

به عنوان مثال پایانی، فرض کنید می‌خواهیم تعداد پست‌های هر کاربر را در یک وبسایت نمایش دهیم و این در حالیست که بین کاربران، افراد دارای نام کاربری با جهت‌گیری راست‌به‌چپ نیز وجود دارد. با قرار دادن نام کاربری افراد درون عنصر bdi می‌توانیم از بروز مشکلاتی که دیدیم، جلوگیری کنیم.

تغییر جهت فعلی متن

همانطور که گفته شد، حهت‌گیری کاراکترها با استفاده از الگوریتم bidi تعیین می‌شود. با استفاده از عنصر bdo می‌توانیم جهت‌گیری پیش‌فرضی را که این الگوریتم برای کاراکترهای متنی تعیین کرده، تغییر دهیم. bdo مخفف Bi-Directional Override است و جهت متن را با استفاده از صفتی با نام dir تعیین می‌کند. این صفت می‌تواند یکی از مقادیر ltr یا چپ‌به‌راست و rtl یا راست‌به‌چپ را دریافت کند. کدهای زیر را اجرا کنید و ببینید که چطور استفاده از عنصر bdo برای پاراگراف دوم و چهارم سبب تغییر جهت‌گیری پیش‌فرض متن این پاراگراف‌ها شده است.

Copy Icon HTML
<p>the text is left to right.</p>
<p><bdo dir="rtl">the text is right to left.</bdo></p>
<p>این متن از راست به چپ نمایش داده می‌شود.</p>
<p><bdo dir="ltr">این متن از چپ به راست نمایش داده می‌شود.</bdo></p>