استخدم lang وdir وتصريح الترميز بحكمة، واهزم مصائد التطبيع والاتجاهية في Unicode.
افتح هذا الدرس في Kodokonالسمة lang أكثر بكثير من مجرد بيانات وصفية: فهي تقود أصوات قارئات الشاشة، والفصل المقطعي (hyphens: auto لا يعمل بدونها)، واختيار محارف CJK (المحرف التصويري ذاته يُرسَم بشكل مختلف في اليابانية والصينية)، وعلامات الاقتباس التي يولّدها <q>، ومحدِّد CSS المسمّى :lang(). وهي موروثة: صرّح بها على <html> بوسم BCP 47 (en، en-GB، ja) وتجاوَزها محليًا عند كل تغيير في اللغة.
<html lang="en">
<p>She said: <q>hello</q>.</p>
<p lang="fr">Elle a dit : <q>bonjour</q>.</p>
</html>تقلب dir=rtl المحاذاة الافتراضية والترتيب البصري للمحارف ذات الاتجاهية المحايدة. أما بالنسبة لمحتوى المستخدم غير المتوقّع، فتختار dir=auto الاتجاه بناءً على أول محرف ذي اتجاهية قوية. يعزل العنصر <bdi> مقطعًا عن الخوارزمية ثنائية الاتجاه: بدونه، يرى اسم مستخدم عربي متبوع بـ ": 12 نقطة" ترقيمَه يُعاد ترتيبه إلى هراء.
<p dir="auto">مرحبا - inferred direction: RTL</p>
<ul>
<li><bdi>مستخدم</bdi>: 12 points</li>
<li><bdi>Alice</bdi>: 8 points</li>
</ul>يجب أن يظهر تصريح <meta charset=utf-8> ضمن أول 1024 بايت من المستند: يُجري المتصفح مسحًا مسبقًا محدودًا بتلك النافذة قبل اختيار ترميز. بلا تصريح وبلا ترويسة HTTP، يعتمد الترميز الافتراضي على إعدادات لغة المستخدم المحلية (غالبًا windows-1252 في أوروبا الغربية) - وليس UTF-8 أبدًا. أما علامة ترتيب البايتات (BOM) في بداية الملف فتتجاوز كل شيء آخر، بما في ذلك ترويسة HTTP.
const composed = "\u00e9";
const decomposed = "e\u0301";
console.log(composed === decomposed); // false
const nfc = decomposed.normalize("NFC");
console.log(composed === nfc); // trueيخزّن macOS بعض أسماء الملفات في شكل مُفكَّك (NFD): لذا قد يختلف "é" الآتي من تحميل عن ذلك المكتوب على لوحة المفاتيح. طبّع بشكل منهجي كل مدخلات المستخدم إلى NFC قبل تخزينها أو مقارنتها. وأخيرًا، .length يحسب وحدات ترميز UTF-16، لا المحارف المُدرَكة: فرمز إيموجي عائلة يجمع أكثر من سبع منها؛ استخدم Intl.Segmenter لعدّ الرسوم الحرفية (graphemes) الحقيقية.
<meta charset=utf-8>؟<head><body>dir=auto اتجاه عنصر؟<html>===؟