تخطَّ إلى المقالة

من اليمين إلى اليسار نُشر زمن القراءة 14 د

عيوب الكتابة من اليمين إلى اليسار التي لا تصلحها الخصائص المنطقية

إحدى عشرة قاعدة انعكاس مكتوبة باليد تكفي موقعًا من 15,142 سطرًا، وهذه هي الحجّة للخصائص المنطقية بالأرقام لا بالثناء. أما العيوب السبعة التي وصلت فعلًا إلى القارئ العربي فكانت كلها في مكان آخر — في transform، وفي ترتيب DOM، وفي محرّك التشكيل، وفي نافذة قصّ — والعثور عليها احتاج أداة قياس مختلفة.

باختصار

تجدها بتحويل كل عيب في الاتجاه إلى تأكيد على خاصّية يجري على كل مسار عربي، لأن الأداتين اللتين يلجأ إليهما معظم الفرق لا تنفعان: مرجع المقارنة بالبكسل يموت لحظة يتغيّر الخط العربي، وaxe-core 4.11.0 يقدّم 104 قواعد ليس فيها واحدة عن اتجاه النص. وبوابة هذا الموقع تقدّم 37 تأكيدًا من هذا النوع بأربعة عروض على المسارات العربية التسعة عشر كلها، وأنفعها طرحٌ واحد — قيمة scrollWidth للمستند ناقص innerWidth للنافذة، بتسامح قدره بكسل واحد — يلتقط دفعةً واحدة كل إزاحة لم تنعكس وكل إشارة transform خاطئة. وما زالت الخصائص المنطقية تحمل الحمل الأثقل، لكنها لا تبلغ transform ولا ترتيب DOM ولا حلّ الاتجاهين ولا تقسيم النص ولا مقاييس الخط، وهناك كانت العيوب السبعة المنشورة كلها.

ما تخرج به

  1. الخصائص المنطقية تستحقّ كل سطر — 78 إعلانًا على المحور السطري في 15,142 سطرًا من CSS تركت هذا الموقع بإحدى عشرة قاعدة انعكاس صريحة — وهي تقف عند حدّ نموذج الصندوق في CSS.
  2. لا يعرف transform الاتجاه بحكم المواصفة، فوجب أن تصير الإشارة متغيّرًا: تعيد inlineSign موجب واحد في المستند العربي وسالب واحد في غيره، وكانت هي الفرق بين عشر دراسات حالة يمكن بلوغها وصفر.
  3. ترتيب التركيز المتسلسل هو ترتيب DOM ولا يقرأ الاتجاه إطلاقًا، وبهذا بقي أغلى عيب في هذه المجموعة غير مرئي على الشاشة.
  4. حين تتغيّر الطبقة الخاضعة للقياس، وجب أن تتغيّر أداة القياس معها: استبدال عائلة واحدة بعائلتين عربيتين أبطل مرجعًا بالبكسل مضبوطًا بايتًا ببايت في إيداع واحد.
  5. التأكيد على خاصّية لا يؤكّد إلا الخصائص التي خطرت لأحدهم — ففحص المقاطع المنقلبة في هذا الموقع مكتوب على الأبناء من العناصر، وعدّادٌ أجزاؤه عناصر flex مجهولة يمرّ من تحته دون أن يلتقطه.

42 files · 15,142 lines · 78 declarations

ما الذي تشتريه لك الخصائص المنطقية فعلًا؟

أعطِ الأداة حقّها أولًا، وأعطِه بالأرقام. تبلغ أوراق أنماط هذا الموقع 15,142 سطرًا في 42 ملفًا، منها 78 سطرًا إعلانات منطقية على المحور السطري — padding-inline وmargin-inline وinset-inline-start وtext-align: start. ويقابلها إحدى عشرة كتلة قاعدة انعكاس صريحة مقيّدة بجذر rtl، وتسع عشرة كتلة أخرى مقيّدة باللغة العربية ليس فيها واحدة للانعكاس. يتولّى التتالي مشكلة الاتجاه وحده تقريبًا، ويتولّاها في الطبقة التي تغطّي معظم الصفحة.

والحدّ موثَّق لا مُكتشَف. فمرجع MDN نفسه لهذه الوحدة يسرد المكافئات المنطقية للقياس والهوامش والحشو والحدود والإزاحات وfloat وclear وresize وcaption-side وtext-align، ثم يعدّد الخصائص التي لا مكافئ لها ولن يكون: transform وtransform-origin وbackground-position وbox-shadow وtext-shadow وزوايا linear-gradient وموضع radial-gradient وfilter. والسبب المعلن واحد فيها جميعًا — أنها تعمل في فضاء إحداثيات مرسوم لا في تدفّق المستند. أما التحويلات المنطقية فمسألة مفتوحة في فريق عمل CSS منذ 23 أكتوبر 2018، برقم 311 في w3c/fxtf-drafts، وما زالت مفتوحة.

فالسؤال المثير ليس ما الذي يغطّيه التتالي، بل ما الذي يبقى خارجه؛ وما بقي في هذا الموقع تبيّن أنه خمس طبقات لا تعرّف المنصّة فيها معنًى للمنطقي أصلًا: فضاء الإحداثيات الذي يعيش فيه transform، وترتيب DOM، وكيف تحلّ خوارزمية الاتجاهين مقطعًا، وكيف يقطّع مُقسِّم النص كلمةً، وماذا تقيس مقاييس الخط نفسه. سبعة عيوب وصلت من هذا الترميز إلى القارئ العربي، وكل واحد منها كان في واحدة من تلك الخمس.

كل خاصّية فيزيائية لا مكافئ منطقي لها ويستعملها هذا الترميز فعلًا، وما كلّفته كلٌّ منها من قواعد مكتوبة باليد. الأعداد من مسحٍ لـ src/styles بعد نزع التعليقات.
الخاصّية مكافئ منطقي كتل قواعد الانعكاس
padding-inline وmargin-inline وinset-inline، بكل صورها نعم — 78 إعلانًا تستعملها 0
translateX وtranslate3d لا 2
scaleX لا 2
transform-origin لا 1
زاوية linear-gradient لا 2
ترتيب عناصر flex في قيمة مركّبة لا — الترتيب يتبع الاتجاه 3
ترتيب التركيز المتسلسل لا — ترتيب DOM، لا يتأثّر 1

ولم يعد الدعم قيدًا أيضًا. يضع caniuse مواصفة CSS Logical Properties and Values Level 1 عند 96.42 بالمئة عالميًّا، بدعم كامل من Chrome 89 وEdge 89 وFirefox 66 وSafari 15. أما الثغرة التي ما زال تحليل الثغرات العربية من W3C يسجّلها فأضيق وأدقّ: الكلمات المفتاحية المنطقية داخل الصيغ المختصرة ليست مدعومة جيدًا، ولهذا كانت الأعداد أعلاه للصيغ المطوّلة.

src/runtime/pages/projects.js:180-201

لماذا يتجاهل transform الجهة التي تُقرأ منها الصفحة؟

يضع فهرس المشاريع عشر دراسات حالة على قضيب أفقي: مسار يسير جانبًا كلما نزلت الصفحة. وورقة أنماطه منطقية بالكامل — المسار inset: 0 مع padding-inline: 8vw — فيفيض المسار في المستند العربي إلى اليسار كما ينبغي تمامًا. لم يكن في CSS شيء خطأ.

ثم أزاحه JavaScript إلى اليسار أكثر. وبالقياس على مسار المشاريع العربي، عند التمرير إلى نهاية القضيب، بلغت الخاصّية المخصّصة التي يقرؤها المسار −2,531 فدفعت مسارًا بدأ أصلًا خارج الحافة اليسرى إلى خارجها أكثر. صفر من البطاقات العشر كان داخل الشاشة، عند 1440 وعند 390 سواء، وظلّ العدّاد في الزاوية يقرأ 10 طوال النزول. لم يكن بوسع قارئ عربي أن يبلغ دراسة حالة واحدة عبر القضيب.

والسبب في المواصفة لا في المتصفّح. تعرّف CSS Transforms Level 1 فضاء الإحداثيات بمحورين: المحور X يزداد أفقيًّا إلى اليمين، والمحور Y يزداد رأسيًّا إلى الأسفل. ولا مصطلح لترتيب القراءة في ذلك التعريف كله، فيسير translate3d الجهة الفيزيائية نفسها في المستندين مهما قال الاتجاه. والمقدار هو الكمّية نفسها في المستند العربي وفي الإنجليزي؛ الإشارة وحدها حقيقة عن ترتيب القراءة.

العلاج كله، في ثلاثة ملفات. وكانت الدالّة المساعدة موجودة، غير مستعملة في الإنتاج، قبل اكتشاف العيب.
// src/runtime/core/env/direction.js — 64 سطرًا، بلا أي استيراد
export function isRtl(doc) {
  return (doc?.documentElement?.dir ?? '') === 'rtl'
}
 
export const MIRROR = Object.freeze({ right: 'left', left: 'right' })
 
export function inlineSign(doc) {
  return isRtl(doc) ? 1 : -1
}
 
// src/runtime/pages/projects.js — ردّ نداء التمرير
// كان:  const x = (-progress * span).toFixed(1)
const sign = inlineSign(doc)
const x = (sign * progress * span).toFixed(1)
 
// tests/unit/motion-primitives.test.mjs
assert.equal(railTravel(4000, 1440, false), -2560)
assert.equal(railTravel(4000, 1440, true), 2560)

ونُشر العيب نفسه مرّتين بالشكل نفسه. فقضيب الرحلة في الصفحة الرئيسية محشوّ بـ padding-inline: 75vw، فكان مساره يفيض هو أيضًا إلى اليسار كما ينبغي، وكان انتقاله هو أيضًا يكتب سفرًا سالبًا يدويًّا — فيسحب مسارًا فائضًا إلى اليسار أصلًا خارج قصّه حتى تختفي بطاقات الفصول الأربع كلها. وبالقياس بعد العلاج: ينجرف المسار +1,199 بكسل في الصفحة الرئيسية العربية و−1,199 في الإنجليزية، ويؤكّد اختبار وحدة أن المقدار واحد وأن الإشارة وحدها تختلف.

وهنا أيضًا تعجز خطوة بناء تقلب CSS عن البلوغ. تعكس RTLCSS الإعلانات الحسّاسة للاتجاه، ومنها التحويلات، وتوثيقها نفسه صريح في أن بعض القيم لا يمكن عكسها من دون توجيه من المؤلّف. إنها تقلب النسخة المبنيّة من ملف CSS — والرقم الذي كسر هذا القضيب لم يكن موجودًا وقت البناء. كان يُحسب في كل إطار ويُكتب في خاصّية مخصّصة، وهذا موضع لا يراه أي تحويل لورقة أنماط. وسحب اللمس المضاف إلى القضيب نفسه هذا الأسبوع يأخذ اتجاهه من الدالّة المساعدة ذاتها، فإصبع يتحرّك يمينًا يتقدّم في المجموعة العربية بدل أن يرجع بها.

والقضيب الذي حدث فيه هذا ما زال المدخل إلى الأعمال العشرة — فهرس المشاريع، وهو الآن قابل للبلوغ بثلاث لغات.

legacy-forensics/a10-css.md §AA

لماذا يُقرأ عدّاد بالمقلوب وليس فيه شيء عربي؟

أوضح مجموعة تعليمية لهذه الحالة قيست على abbod.de القديم — الموقع قبل إعادة البناء، وهو النسخة الذهبية التي يُقارَن بها هذا المشروع — وهي قائمة قيم لاتينية عادية تظهر مقلوبة في الصفحات العربية. فهرس بطاقة، ولون ستّ عشري، ومعرّف على شبكة اجتماعية، ورقم حجم، وشعار كلمة المحمِّل نفسه. ليس في واحد منها حرف عربي واحد.

وكان ملف التحليل الجنائي الذي سجّلها قد قسم العائلة سلفًا إلى الآليتين اللتين تحتاجهما، والتمييز هو الجزء النافع. فحين تجلس القيمة كلها في عقدة نصّية واحدة، تكون خوارزمية يونيكود للاتجاهين هي التي تحلّها مقابل الفقرة المحيطة، والعلاج إعلان اتجاهين على العنصر. وحين تكون القيمة قد قُسّمت عبر صناديق سطرية — عنصر فاصل، أو غلاف لكل حرف — فلا تستطيع الخوارزمية شيئًا البتّة، لأن كل صندوق مقطع بذاته ولم يبقَ لها ما تعيد ترتيبه. تلك الحالة تحتاج ضبط الاتجاه الأساس: direction: ltr.

وتقول UAX رقم 9، المراجعة 51، ذلك في تحديد نطاقها. فهي تحلّ مستوى الفقرة، والمستويات الصريحة للتضمين، والأنواع الضعيفة، والمحايدات، والمستويات الضمنية، وتفعل ذلك كله داخل كل فقرة من المحارف. أما كيف تُرتَّب الصناديق السطرية أو العناصر فخارج نطاقها. ذلك الترتيب من عمل مواصفة flexbox، والقسم 5.1 فيها لا لبس فيه: المحور الرئيسي لحاوية flex صفّية له اتجاه المحور السطري نفسه في نمط الكتابة الحالي. فثلاثة عناصر flex تقرأ 01 وشرطة مائلة و04 تُخطَّط إذن بالمقلوب في المستند العربي، وكل بطاقة في قسم الرحلة بهذا الموقع كانت تدّعي أنها الرابعة من واحد.

مقيسة على abbod.de القديم، لا على ما يُنشر اليوم. كل قيمة شيء واحد عند القارئ وعدّة صناديق عند محرّك التخطيط.
كما كُتبت كما ظهرت في الصفحة العربية القديمة ما كانت تحتاجه
01 / 04 04 / 01 direction: ltr — مقسّمة عبر صناديق
LoadAbbod dobbAdaoL direction: ltr — صندوق لكل حرف
#C4552D C4552D# unicode-bidi — عقدة نصّية واحدة
@alaaabbod alaaabbod@ unicode-bidi — عقدة نصّية واحدة
6 KB JS KB JS 6 unicode-bidi — عقدة نصّية واحدة

وسُجِّل عيبان آخران يصعب طبعهما في مقالة: رقم هاتف انقلب إلى هراء، وعيّنة ترميز بدّل وسمها الختامي قوسيه الزاويين فما كان الترميز المعروض للقارئ ليُحلَّل أصلًا. وكلاهما من حالة العقدة النصّية الواحدة، وكلاهما سبب أن هذا الموقع صار يؤكّد على كل مسار عربي أن كل ما داخل عنصر code أو pre يُحسب إلى direction: ltr.

وينقلب العدّاد بسبب المواصفة لا بسبب خلل في المتصفّح، وهذا سهل القول ويستحقّ إعادة الإنتاج. ففي Chromium معزول بلا واجهة تحت جذر rtl، يظهر عدّاد inline-flex يحوي 01 وعنصرًا فاصلًا و10 بصريًّا 10 ثم الشرطة المائلة ثم 01، بمستطيلات أجزاء عند اليسار 748 و768 و776. والترميز نفسه مع direction: ltr وunicode-bidi: isolate يظهر بالترتيب الذي كُتب به، عند المواضع الثلاثة نفسها.

23 sources · 0 chars on /ar/ · 201 on /

لماذا يكتب تقسيم النص الكلمات العربية خطأً؟

تحتاج لفّة المحارف أن يكون كل محرف صندوقًا يمكن تحريكه. وتعرّف CSS Transforms Level 1 العنصر القابل للتحويل بأنه كل ما يحكمه نموذج الصندوق في CSS عدا الصناديق السطرية غير المستبدَلة وصناديق أعمدة الجداول ومجموعات أعمدة الجداول — فعنصر سطري مجرّد لكل حرف ليس منها. وقيس ذلك هنا في انتقال كان ينبغي أن يسافر −70.00 بكسل فسافر 0.00. وجعل كل محرف مولَّد inline-block ليس خيارًا في الأنماط؛ فبدونه لا يفعل التأثير شيئًا.

والصندوق السطري الذرّي لكل حرف صندوق لا يستطيع محرّك التشكيل الوصل عبره، والكتابة المتّصلة كتابة تعتمد فيها صورة الحرف على جيرانه. فكل كلمة عربية تحمل خاصّية التقسيم في هذا الموقع كانت تظهر صفًّا من الصور المنفردة — 23 مصدرًا، منها روابط القائمة الأربعة كلها وكل رابط في التذييل. وكلمة تواصل نفسها خرجت خمسة حروف منفصلة لا تكتب شيئًا. وهذا ليس تدهورًا خفيًّا: إنه خطأ إملائي، على كل عنوان تنقّل في الموقع.

ولا علاج في الأنماط، وهذا هو مقصد القسم كله. فإعادة المحارف إلى inline تُرجع الوصلات وتقتل التحويل؛ وتركها inline-block يبقي التحويل ويقتل الوصلات. والمطلبان متنافيان بحكم المواصفة، وتسرد CSS Text 3 في القسم 7.3 الشروط التي يجب عندها أن ينكسر التشكيل عند حدّ صندوق سطري — هامش أو حدّ أو حشو سطري غير صفري، وvertical-align غير ابتدائي، وحدّ عزل للاتجاهين. وتقول GreenSock الشيء نفسه عن أداتها بكلام أوضح: لم يُصمَّم SplitText للغات التي تُكتب من اليمين إلى اليسار، ولا إصلاح مخطّط له.

  1. التأثير يطلب صندوقًا لكل محرف لفّة الحرف الواحد تحويل، والتحويل لا يُطبَّق على عنصر سطري غير مستبدَل. فوجب أن تكون المحارف المولَّدة inline-block حتى تحرّك الحركة شيئًا أصلًا.
  2. المُقسِّم يستجيب، بدقّة العنقود الكتابي يقطّع SplitText 3.13 عبر Intl.Segmenter بدقّة العنقود الكتابي (grapheme) ويغلّف كل عنقود في عنصر خاص به. وهذا سلوك صحيح للوحدة التي طُلبت منه.
  3. محرّك التشكيل يقف عند الحدّ صار كل عنصر من تلك العناصر صندوقًا سطريًّا ذرّيًّا، والوصلات التي تجعل الكلمة العربية كلمة لا تعبر واحدًا منها. فتتفكّك الحروف، بالترتيب الذي كُتبت به، ولا تكتب شيئًا.
  4. خوارزمية الاتجاهين لا تنقذه فهي ترتّب المحارف داخل الفقرة، لا الصناديق داخل السطر. وفي كلمة لاتينية مقسّمة بالطريقة نفسها تكون النتيجة صورة المرآة للمشكلة ذاتها: تنقلب الحروف، لأن كل واحد منها مقطع بذاته.
  5. فيغيّر التقسيم وحدته طلبُ الكلمات والحروف يصير طلبًا للكلمات؛ وطلبُ الأسطر والكلمات والحروف يصير أسطرًا وكلمات؛ والمصدر الذي طلب الحروف وحدها يرتدّ إلى الكلمات بدل أن ينقسم إلى لا شيء.
  6. ويرتبط باللغة لا بالاتجاه العبرية تُكتب من اليمين إلى اليسار ولا تتّصل حروفها، ففحص الاتجاه كان سيكسر العبرية لسبب لا يصحّ عليها. يقرأ الفحص وسم اللغة الفرعي، وله اختبار وحدة بمستند عبري في جذر rtl يعيد false.
السلسلة، حلقةً حلقة. ظهرت تواصل كـ ت و ا ص ل على 23 مصدرًا، والموضع الوحيد لكسر السلسلة هو الخطوة الأخيرة.

وتُؤكَّد النتيجة في الاتجاهين لا في اتجاه واحد، وهذا أهمّ ممّا يبدو. تفحص البوابة أن المستند العربي فيه صفر عقدة حرف وأن الإنجليزي فيه 201 منها، وتفحص منفصلةً أن المستند العربي ما زال فيه كلمات وأسطر تُحرَّك — لأن فحصًا يؤكّد صفر حروف وحدها كان سينجح بالسعادة نفسها في صفحة لم ينقسم فيها شيء أصلًا.

وسقط عيب ثانٍ من العلاج نفسه، وكان خافيًا لسبب يستحقّ التسجيل. فمسافة سفر اللفّة كانت مكتوبة رقمين حرفيين يصادف أنهما صحيحان للعناوين اللاتينية: ارتفاع سطر 1 مع إزاحة ظلّ تساوي حجم الخط، فيكون سالب مئة بالمئة من صندوق المحرف وem واحد البكسل نفسه. أما في العناوين العربية، المضبوطة على 1.55، فيكفّان عن كونهما البكسل نفسه — إذ هبطت الكلمة الداخلة 0.45em تحت الخارجة، وهو انزياح خط الأساس الذي أبلغ عنه صاحب الموقع في كل رابط عربي في الموقع. والعلاج يقرأ الإزاحة المحسوبة للتوأم نفسه بدل افتراضها.

وللنصف الخاص بالتقسيم مقالته، ومنها ما يراه القارئ العربي وحدةً تستحقّ التحريك — تقسيم النص في كتابة متّصلة.

derived from Zain hhea · size-adjust 112%

كيف تحوّل نافذة قصّ كلمة عربية إلى كلمة أخرى؟

لفّة العنوان في هذا الموقع ثلاثة إعلانات في ثلاثة مواضع: ارتفاع سطر في ورقة اللغة، وclip-path في الورقة نفسها، وإزاحة text-shadow في مكوّن الزر. وهي معًا رقم واحد. فنافذة القصّ هي الفتحة المرئية؛ والظلّ هو النسخة التوأم من الكلمة تنتظر تحتها؛ وصندوق السطر يقرّر أين يجلس كلاهما. غيّر واحدًا دون الاثنين الآخرين ينكسر التأثير بشكل يبدو كمشكلة في الخط.

وبتطبيق الهندسة اللاتينية على عنوان عربي — ارتفاع سطر 1، ونافذة تقطع عند 94 بالمئة من الصندوق، وتوأم على بعد em واحد — يقع القطع 0.153em تحت خط الأساس. والياء النهائية في الخط المنشور تنزل 0.5096em. فيُنزع 0.357em من الحبر، وتذهب معه النقطتان تحت الحرف، فتظهر الكلمة حرفًا آخر تمامًا. وقاست النسخة الذهبية هذا بالضبط على رابط تذييلها: كلمة صاحب الموقع نفسها، راسلني، مطبوعةً خطأً عن نفسها.

وفتح صندوق السطر وحده لا يصلحها ويُدخل عيبًا ثانيًا. فعند 1.55 والنافذة ما زالت عند 94 بالمئة يجلس القطع 0.395em تحت خط الأساس وتبقى الياء مقصوصة بمقدار 0.115em — ويبدأ حبر التوأم الآن على بعد 0.845em من الأعلى، داخل نافذة تبلغ 1.457em، فيظهر صفّ شبح من الكلمة التالية تحت كل عنوان. فالأرقام الثلاثة يجب أن تتحرّك معًا، والترتيب هو الثابت: التوأم تحت النافذة، والنافذة تحت الحبر.

  • 0.153 em القطع اللاتيني، تحت خط الأساس ارتفاع سطر 1، ونافذة 94 بالمئة، وتوأم 1em
  • 0.5096 em نزول ي في آخر الكلمة أعمق حبر في الخط المنشور
  • 0.357 em الحبر الذي تنزعه النافذة راسلني تُطبع راسلنى
  • 0.705 em القطع المنشور، تحت خط الأساس ارتفاع سطر 1.55، ونافذة 114 بالمئة، وتوأم 2em
مشتقّة من مقاييس hhea للخط المنشور نفسه — صعود 869، ونزول 459، و800 وحدة في الـ em — عند size-adjust بنسبة 112 بالمئة. وورقة الأنماط تصرّح بآخر هذه الأرقام بنفسها.

والحالة المنشورة تترك الياء بفسحة 0.196em، وتضع قاع النافذة عند 1.767em وقمّة حبر التوأم عند 1.845em، فتخفيه بمقدار 0.078em. وثمانية وسبعون جزءًا من ألف من الـ em هي كل الهامش بين تأثير يعمل وصفّ شبح مرئي، وهذه هي الحجّة لاشتقاق الأرقام الثلاثة بدل تحريكها بالحدس.

والالتفاتة الأخيرة هنا عن النطاق لا عن الهندسة. فقد كُتب العلاج للمستند العربي، وبقي العيب حيًّا في المستندين الإنجليزي والألماني — على الكلمة العربية الوحيدة فيهما، وهي عنوان مبدّل اللغة نفسه، الذي يُطبع في كل صفحة ليتعرّف عليه قارئ لا يقرأ اللغة الحالية. وقد ورثت تلك الكلمة عائلة لاتينية لا عربية فيها، وتباعد نصّ المتن، وصندوق سطر من em واحد، ونافذة 94 بالمئة. فالمستند اللاتيني ليس مستندًا خاليًا من العربية، والقاعدة اليوم ترتبط بلغة المقطع لا باتجاه الصفحة.

وارتفاع السطر الذي يفتح تلك النافذة قياس بذاته لا نسبة — حساب الأرضية الحقيقية.

وsize-adjust الذي يقيس ذلك كله يأتي من سنّة وألف، لأن ارتفاع الـ x لا يعني شيئًا هنا: قياس خط عربي مقابل خط لاتيني.

src/styles/components/site-nav.css:68-108

لماذا يحتفظ الرأس بترتيبه اللاتيني في الصفحة العربية؟

لم يكتب أحد قاعدة من اليمين إلى اليسار للرأس. وانعكس رغم ذلك، من خاصّية اتجاه واحدة على عنصر الجذر وjustify-content: space-between واحدة، وظلّ ينعكس عبر سبع حاويات متداخلة لم يُسأل أيٌّ منها عن ذلك قط. والعيب هنا صنعه عدمُ كتابة CSS، وهذا نمط الفشل الذي لا يدقّق فيه أحد.

وما كلّفه ذلك الانقلاب لم يكن بصريًّا. فترتيب التركيز المتسلسل هو ترتيب DOM ولا يتبع الاتجاه إطلاقًا، فكان زائر لوحة المفاتيح في الصفحات العربية ينتقل من اليسار إلى اليمين عبر شريط يُرسم من اليمين إلى اليسار. ويطلب البند 2.4.3 من WCAG أن يحفظ ترتيب التركيز المعنى وقابلية التشغيل، لا أن يطابق الترتيب البصري، فهذا وحده ليس إخفاقًا في المطابقة — وسبب تثبيت الشريط في هذا الموقع قرارٌ من صاحبه بأن الشريط كائن للعلامة، وعودة ترتيب DOM والترتيب البصري إلى الاتفاق فائدة حقيقية تتبع ذلك القرار لا تبرير له.

والعلاج يطفئ السبب لا الأعراض. فإعلان direction: ltr واحد على الشريط وعلى غلاف قائمته يغلب سبعة إعلانات row-reverse، والحاوية الثامنة التي يضيفها أحدهم العام القادم تكون صحيحة افتراضًا بدل أن تكون خطأً بالإهمال. والاتجاه هو الخاصّية الوحيدة التي يقرؤها كل انقلاب ضمني تحته: المحور الرئيسي في flex، وtext-align: start، وكل خاصّية منطقية، وترتيب الصناديق السطرية. ثم تُستعاد المقاطع العربية داخله فرادى، مع unicode-bidi: isolate حتى لا يعيد مقطع ترتيب جيرانه في الصندوق من اليسار إلى اليمين الذي صار يحويه.

أطفئ السبب ثم استعد المقاطع. والنصفان لازمان: الأول وحده يترك النص العربي يُحلّ مقابل أساس من اليسار إلى اليمين.
/* src/styles/components/site-nav.css */
/* سبب واحد، لا سبعة أعراض */
html[dir='rtl'] .nav,
html[dir='rtl'] .nav-menu-w {
  direction: ltr;
}
 
/* والعربية داخله ما زالت عربية */
html[dir='rtl'] :is(.nav, .nav-menu-w)
  :is(.text-nav-link, .text-eyebrow, .nav-lang-label, .btn-text.is-lang-ar) {
  direction: rtl;
  unicode-bidi: isolate;
}

والأداة نفسها تثبّت ثنائية الشيفرة والتصميم في الصفحة الرئيسية، لسبب آخر. فصور الخلفية فيها موضوعة فيزيائيًّا ولم تُعكس قط، فتحت الانقلاب الضمني كانت حجّة كل عمود تجلس أمام الوجه الخطأ — وكان النص البديل يقول ذلك صراحةً. وتثبيت التخطيط هو ما يعيدهما إلى موضعهما؛ واحتاجت طبقة الحركة خاصّية انسحاب مقابلة على ستة عناصر حتى تبقى مسحتا السطرين متقابلتين عبر الفجوة الوسطى.

وأمر ينبغي معرفته قبل اللجوء إلى الصنف الزائف :dir() لكتابة قواعد كهذه. فهو متاح على نطاق واسع منذ ديسمبر 2023، ولا يقرأ إلا الاتجاه الدلالي المعلن في المستند. وهو لا يحسب حساب خاصّية direction في CSS، فحاوية انسحبت لتوّها بـ direction: ltr تبقى عنده عنصرًا من اليمين إلى اليسار. ومحدِّدات الخصائص على الجذر تؤدّي هنا عملًا حقيقيًّا لا يستطيعه الصنف الزائف.

والتباعد بين الحروف ينتمي إلى القسم نفسه لأنه القرار نفسه في طبيعته، ولأنه معياري لا جمالي. يقول القسم 7.2.1 من CSS Text 3 إن وكيل المستخدم الذي لا يستطيع تمديد النص المتّصل دون كسر وصلاته يجب ألّا يطبّق تباعدًا بين أي زوج من حروف تلك الكتابة إطلاقًا، وتصف المواصفة في مثالها التباعد الموزّع بالتساوي على العربية بأنه سيّئ، مع ملاحظة أنه يكسر الوصلات. وسبب حاجة الموقع إلى تجاوز صريح رغم ذلك أن التباعد معلَن على العناصر نفسها — العناوين الفرعية والأزرار وروابط التنقّل وخطوط العرض — لا موروثًا، وهذا ما يجعله !important الشامل الوحيد الذي يعدّه المشروع مبرَّرًا.

noise-floor.json · measured 2026-08-19

لماذا لا تستطيع لقطة شاشة ضبط أيٍّ من هذا؟

البوابة البصرية الرئيسية في هذا المشروع مقارنة بالبكسل مقابل النسخة الذهبية، ولا محور للّغة فيها البتّة. فبيان العروض لا يعلن أيًّا منها، ومكتبة السيناريوهات لا منطق لغة فيها، وخطوة الالتقاط تقرأ حقل لغة من السيناريو ولا سيناريو يضبطه. وتوثيق البوابة يقول ذلك بنفسه، في جدول عنوانه ما لا تستطيع هذه البوابة إثباته: التخطيط عبر اللغات، ومنه الاتجاه من اليمين إلى اليسار، مسرود بوصفه غير مغطّى، مع ملاحظة أن اتجاه عنصر الجذر يُقارَن بالضبط لكنه لم يُرصد قط إلا ltr.

وحيث تعمل فهي قريبة من الكمال، وتلك هي المصيدة. فبالقياس على 19 نقطة في 2026-08-19، كانت نسبة الفرق البنيوي بالبكسل صفرًا عند كل مئين، وكانت 18 من النقاط التسع عشرة متطابقة بايتًا ببايت عبر جولتين للمرجع نفسه؛ والاستثناء الوحيد شريط متحرّك التُقط حيًّا عن قصد. والعتبة مضبوطة من ذلك القياس عند 0.0001، لأن العتبة تُضبط بما تستطيع أداة القياس إثباته. ثم تغيّر الخط العربي من عائلتين إلى عائلة واحدة، بتعليمات من صاحب الموقع، فاختلف كل بكسل عربي في الموقع بحكم البناء. وأداة بهذه الدقّة لا تتدهور برفق. إنها تنتقل من البرهان إلى جدار أحمر في إيداع واحد.

ولا يستطيع فاحص سهولة الوصول سدّ الثغرة أيضًا، ويستحقّ الأمر تحديدًا لأنه البديل الذي تفترضه معظم الفرق. يقدّم axe-core 4.11.0 عدد 104 قواعد. وترشيح القواعد الـ 104 كلها بمعرّف القاعدة ووصفها ونصّ مساعدتها بحثًا عن الاتجاه أو الانعكاس أو الاتجاهين أو ترتيب التخطيط يعيد ستًّا، منها أربع تتحقّق من وجود خاصّية lang وصحّة صيغتها، واثنتان مطابقتان زائفتان على كلمة structured. ويشغّل هذا الموقع الفاحص على كل مسار بعرضين — 144 فحصًا في 2026-08-24، وخمس مخالفات — وقد تعايش ذلك المسح مع العيوب السبعة المذكورة هنا كلها.

  • 18 من 19 نقطة متطابقة بايتًا ببايت جولتان للمرجع نفسه، 2026-08-19
  • 0.0001 عتبة الفرق بالبكسل مضبوطة بما تستطيع الأداة إثباته
  • 104 قاعدة في axe-core 4.11.0 144 فحصًا عبر الموقع في 2026-08-24
  • 0 من تلك القواعد عن الاتجاه ولا واحدة عن الانعكاس أو الاتجاهين أو ترتيب التخطيط
أداتا القياس اللتان كانتا موجودتين سلفًا، وما رأته كلٌّ منهما وما لم ترَه. والرقمان الأخيران من جولة واحدة مؤرَّخة؛ وقاعدة البيت أن رقمًا بلا تاريخه ادّعاء.

والسابقة لما ينبغي فعله حيال ذلك كانت موجودة في المستودع سلفًا. فمحور مقارنة canvas مُعلَّم بأنه محجوب وغير مفروض، لأن أرضية الضجيج المقيسة له هائلة — نسبة فرق عند المئين الخامس والتسعين قدرها 0.025829 عبر 89 عيّنة — والمنطق المسجَّل أن بوابةً لا تميّز الانحدار من الضجيج أسوأ من لا بوابة، لأنها تعلّم الناس تجاهلها. ومقارنةٌ أُبطل مرجعها عمدًا هي الإخفاق نفسه بسبب مختلف، ولهذا كان الجواب هنا أداة جديدة لا عتبة مرخاة ولا صفّ استثناء دائمًا.

وكيف قيست تلك الأرضية من الضجيج، ولماذا يُفرض محور ولا يُفرض آخر، في مقالة أرضية الضجيج.

ولمسح سهولة الوصول قصّته عن الشروط — صارت 707 عقدة تباين خمسًا، ونشر الخمس هو المقصد — في مقالة الإيجابيات الكاذبة في التباين.

37 checks · 4 viewports · 19 Arabic routes

ماذا يؤكّد التأكيد على خاصّية

ما حلّ محلّ لقطة الشاشة مجموعةُ خصائص، واحدة لكل عيب. تقدّم البوابة 37 تأكيدًا: ثمانية لكل عرض عند 390 و991 و992 و1440 بكسلًا، وخمسة فحوص مزدوجة تُجري المستند العربي والإنجليزي أحدهما مقابل الآخر. وكل واحد من الثمانية كان عيبًا منشورًا قبل أن يكون فحصًا، وهذا شرط الدخول الوحيد الذي يعترف به الملف. وكل رقم مذكور هنا مقروء من ذلك المصدر لا من جولة — فالبوابة تحتاج خادمين محليين ولم يُشغَّل أيٌّ منهما لهذه المقالة.

وقائمة مساراتها مقروءة لا مكتوبة. فالمسارات العربية تأتي من بيان المسارات المنشور، مرشَّحةً باللغة، ويرمي الملف خطأً إن أعاد ذلك الترشيح لا شيء. وقد أثمر ذلك القرار هذا الأسبوع: انتقل البيان من 72 وثيقة و20 مسارًا عربيًّا إلى 69 و19 حين أُحيلت صفحة مشروع إلى التقاعد، واستوعبت البوابة الحذف بلا تعديل، لأن الفحوص الثمانية لكل عرض تتجمّع فوق أي مسارات يسمّيها البيان.

وأنفع الـ 37 واحدًا طرحٌ. فهو يأخذ في كل مسار عربي قيمة scrollWidth لعنصر المستند، ويطرح منها innerWidth للنافذة، ويتسامح ببكسل واحد. ذلك السطر الواحد يلتقط كل إزاحة فيزيائية لم تنعكس، وكل صندوق ذي سقف صلب تفيض منه العربية، وقضيبًا يسافر في الجهة الخطأ، دفعةً واحدة — وهو ما يحوّل تدقيق الموقع كله بالعربية من مهمّة قراءة إلى قياس.

قواعد الطباعة في ورقة اللغة 16 كتلة
قواعد الانعكاس في أوراق الأقسام 7 كتل
وحدات JavaScript تملك اتجاهًا 6 وحدات
قواعد الانعكاس في أوراق المكوّنات 3 كتل
قواعد لغة خارج ورقة اللغة 3 كتل
قاعدة انعكاس في ورقة اللغة كتلة واحدة
أين يُتَّخذ فعلًا قرارُ اتجاه أو لغة في هذا الترميز، معدودًا بكتل القواعد وبالوحدات البرمجية.الأعمدة بمقياس قواعد الطباعة الستّ عشرة في ورقة اللغة. وللمقارنة: الإعلانات المنطقية الـ 78 على المحور السطري لم تحتج قرارًا البتّة.

وبقيّة الثمانية مملّة عن عمد، والمملّة هي التي تلتقط انحدار البناء. فكل مسار عربي يجب أن يعلن نفسه من اليمين إلى اليسار وعربيًّا على عنصر الجذر. ولا يجوز لشيء أن يتجاوز حافة سطرية دون سلف يقصّه. وكل عنصر code أو pre يجب أن يُحسب إلى direction: ltr، لأن مقتطفًا يرث اتجاه الفقرة يعيد ترتيب علامات ترقيمه ويكفّ عن كونه ترميزًا صحيحًا. وعبر المسارات التسعة عشر كلها يجب ألّا يكون هناك خطأ واحد في وحدة التحكّم، ولا طلب فاشل، ولا استجابة بالرمز 400 أو أسوأ.

وفحص واحد يصرّح بحدّه، وهذه العادة تستحقّ النقل. فهو يمشي على كل عقدة نصّية في المتن ويؤكّد أن كل مقطع عربي يطلب العائلة العربية أولًا، وأن كل مقطع لاتيني يبقي احتياطًا لاتينيًّا أو أحادي المسافة في مكان ما من مكدّسه. ولا يستطيع تأكيد أكثر من ذلك: فمقطع لاتيني خالص داخل مستند عربي قد يطلب العائلة العربية أولًا بحقّ، لأن واصف unicode-range هو ما يوجّهه إلى ما بعدها — والنمط المحسوب لا يرى هل جرى ذلك التوجيه. وما يستطيع الفحص إثباته أن لا مقطع يطلب عائلة ليس خلفها شيء.

ولذلك التوجيه قصّته، لأن أسماء العائلات وعدت بما لم تسلّمه ملفات الخطوط قط — حين تخطف عائلة عربية نصّك اللاتيني.

src/styles/sections/projects-index.css:841-853

الفحص لا يؤكّد إلا الخصائص التي خطرت لأحدهم

فحص المقاطع المنقلبة يعمّم تعميمًا صحيحًا. فقاعدته المعلنة أن العنصر الذي هو قيمة مركّبة واحدة يجب أن يخطّط أجزاءه بالترتيب الذي كُتبت به، والمميّز الذي يستعمله للمركّبة هو المسافة البيضاء: فهرس بطاقة ومجموعٌ قيمةٌ واحدة تصادف أن أجزاءها ثلاثة عناصر، بينما اسم مشروع إلى جانب رقمه صفّ تخطيط ينبغي أن ينعكس. وقد تعلّم ذلك التمييز بالطريقة الصادقة — أبلغت الجولة الأولى عن ستّ إيجابيات كاذبة في مسار واحد وكانت ستدعو إلى إلغاء عكس صفٍّ كان صحيحًا.

والتنفيذ يجمع أبناء العنصر، ويسقط الخارجين عن التدفّق، ويتخطّى ما بقي فيه أقلّ من اثنين. والعدّاد في بطاقات قضيب المشاريع inline-flex يحوي النصّ 01 وعنصرًا فاصلًا والنصّ 10 — ثلاثة عناصر flex واحد منها بالضبط عنصر. فيمرّ الفحص من أمامه. ويُتخطّى أبوه كذلك، بقاعدة المسافة البيضاء، لأن الشارات إلى جانبه تحوي مسافات. فالعيب الذي كُتب الفحص من أجله ما زال في الصفحة التي كُتب فيها، على بعد عشر بطاقات، وتسليم المرحلة الذي يقول إن العدّادين أُصلحا مخطئ في الثاني.

ودقّةٌ في وصف الحالة، لأن هذا استنتاج لا تقرير. فالغياب ثابت وقابل للفحص: تلك الورقة لا تحوي أي إعلان اتجاه البتّة، عند آخر إيداع وفي شجرة العمل. وآلية الانقلاب مُعاد إنتاجها بالضبط في Chromium معزول بلا واجهة. ولم تُرصد على صفحة المشاريع العربية وهي تعمل في هذه الجلسة — وجولة للبوابة كانت ستؤكّدها هناك. ويستعمل الملف نفسه أيضًا margin-left: auto فيزيائيًّا حيث يستعمل العدّاد المصلَح margin-inline-start: auto، وفي صفٍّ من اليمين إلى اليسار عرضه 400 بكسل يمتدّ من 398 إلى 800 يوقع ذلك الفرق الكبسولة عند 724 بدل 399، محشورةً إلى الشارات بدل أن تكون في الطرف الأقصى.

التعميم كان صحيحًا
قيمة مركّبة واحدة، تُخطَّط بالترتيب الذي كُتبت به. وهذا يغطّي عدّادًا ولونًا ستّ عشريًّا ورقم هاتف ومقتطف ترميز في جملة واحدة.
التنفيذ كان أضيق
فهو يقارن الأبناء من العناصر، لأن الحالتين اللتين كُتب عنهما — مقتطف ترميز وعدّاد الرحلة — كان لكلتيهما أبناء من العناصر.
الترميز كان مجهولًا
اثنان من عناصر flex الثلاثة في عدّاد المشاريع نصّ مجرّد بلا عنصر حوله، فيصنع المتصفّح عناصر مجهولة لا يستطيع DOM تعدادها.
الأب مستثنًى عن قصد
ومميّز المسافة البيضاء الذي يمنع الفحص من إلغاء عكس صفوف تخطيط حقيقية يمنعه كذلك من النزول إلى هذا الصفّ.
أربعة أمور وجب أن تصحّ معًا حتى يفوّت فحصٌ العيبَ الذي كُتب من أجله. وآخرها وحده مرئي للقارئ.

والشكل العملي لهذا كله قصير. استعمل الخصائص المنطقية في كل موضع تبلغه، ثم اكتب قائمة بما لا تبلغه في ترميزك — التحويلات، وزوايا التدرّجات، وtransform-origin، والظلال، وترتيب القيمة المركّبة، وترتيب التركيز، والتشكيل، ومقاييس الخط — وافحص تلك القائمة بيدك، مرّة واحدة، على الصفحات العربية. وحوّل كل عيب تجده إلى تأكيد على خاصّية لا على بكسلات. ثم عامل الإفراط في العكس عيبًا كذلك: فمجموعة مشاريع هذا الموقع تترك عمدًا صيغة z-index واحدة بلا عكس، لأن مدخلها منطقي أصلًا، وعكسها مرّة ثانية أخفى تسعًا من الشارات العشر.

وإن كنت تخطّط لبناء بأكثر من كتابة وتفضّل حسم قرارات الاتجاه قبل التخطيط لا بعده، فتلك محادثة قصيرة تستحقّ أن تبدأ مبكّرًا.

أسئلة

هل تتولّى الخصائص المنطقية في CSS الاتجاه من اليمين إلى اليسار وحدها؟

في الطبقة التي تغطّيها، تكاد — فهذا الموقع يكتب 78 إعلانًا منطقيًّا على المحور السطري في 15,142 سطرًا من CSS ويحتاج إحدى عشرة كتلة قاعدة انعكاس صريحة. ثم يسرد مرجع MDN نفسه الخصائص التي لا مكافئ منطقي لها ولن يكون: transform وtransform-origin وbackground-position وbox-shadow وtext-shadow وزوايا linear-gradient وموضع radial-gradient وfilter، لأنها تعمل في فضاء إحداثيات مرسوم لا في تدفّق المستند. أما التحويلات المنطقية فمسألة مفتوحة في فريق عمل CSS منذ أكتوبر 2018 وما زالت بلا حلّ.

لماذا انكسر قضيب المشاريع بالعربية وCSS الخاصة به منطقية أصلًا؟

لأن ورقة الأنماط والسكربت اختلفا على من يملك المحور السطري. فـ padding-inline وinset: 0 جعلتا المسار يفيض إلى اليسار في المستند العربي كما ينبغي، ثم أزاحه ردّ نداء التمرير إلى اليسار أكثر، لأن translate3d يقرأ المحور X، وتعرّفه مواصفة التحويلات بأنه يزداد إلى اليمين مهما كان الاتجاه. وبالقياس: بلغت خاصّية إزاحة المسار −2,531 ولم تكن أي بطاقة من العشر داخل الشاشة، عند 1440 وعند 390 سواء. والعلاج دالّة مساعدة تحمل الإشارة، تُطبَّق في الموضع الوحيد الذي يصير فيه الرقم تحويلًا.

أتفحص على الاتجاه أم على اللغة؟

على أيّهما يكون السؤال عنه فعلًا، فهما سؤالان مختلفان. الاتجاه يقرّر أي جهة يسافر إليها التحويل وأي حافة سطرية تُعدّ خلفك. أما الوصل فخاصّية للكتابة: العبرية تُكتب من اليمين إلى اليسار ولا تتّصل حروفها، فربط قاعدة حذف الحروف بالاتجاه كان سيكسر العبرية لسبب لا يصحّ عليها. والطباعة سؤال لغة أيضًا — تسع عشرة من كتل قواعد الاتجاه أو اللغة الثلاثين في هذا الموقع مقيّدة باللغة العربية، وليس فيها واحدة للانعكاس.

هل يلتقط فاحص سهولة الوصول مشكلات الاتجاه من اليمين إلى اليسار؟

لا. يقدّم axe-core 4.11.0 عدد 104 قواعد، وترشيحها كلها بحثًا عن الاتجاه أو الانعكاس أو الاتجاهين أو ترتيب التخطيط يعيد أربعًا لا تتحقّق إلا من وجود خاصّية lang وصحّة صيغتها، ومطابقتين زائفتين على كلمة structured. ويشغّل هذا الموقع axe على كل مسار بعرضين — 144 فحصًا في 2026-08-24 — وهو لا يرى عدّادًا منقلبًا، ولا قضيبًا يسافر في الجهة الخطأ، ولا حرفًا نازلًا مقصوصًا، ولا ترتيب لوحة مفاتيح يخالف الترتيب البصري. إنه فحص لازم يجيب عن سؤال آخر.

ما الفرق بين direction: ltr وunicode-bidi: isolate؟

يضبط direction الاتجاه الأساس، وهو الذي يقرّر ترتيب عناصر flex، وtext-align: start، وكل خاصّية منطقية، وترتيب الصناديق السطرية داخل العنصر. أما unicode-bidi: isolate فيجعل العنصر يبدو لحاويته كمحرف واحد بديل عن كائن، فلا يستطيع محتواه إعادة ترتيب جيرانه. وتحتاج direction حين تكون قيمة لاتينية قد قُسّمت عبر صناديق سطرية، لأن خوارزمية الاتجاهين لا تنفع هناك. وتحتاج isolate حين تكون قد وضعت للتوّ مقطعًا باتجاه داخل صندوق بالاتجاه الآخر، وكانت المحارف المحايدة عند الحدّ ستُحلّ لولا ذلك مقابل الجهة الخطأ.

المصادر

مقيس في هذا المستودع

  • tools/golden/rtl.mjs التأكيدات الـ 37 على الخصائص، والعروض الأربعة، وقائمة المسارات المشتقّة من البيان، والتضييقان اللذان احتاجهما فحص المقاطع المنقلبة بعد ستّ إيجابيات كاذبة.
  • src/runtime/core/env/direction.js أربعة وستون سطرًا بلا استيراد، تُظهر isRtl وخريطة MIRROR وinlineSign — الحقائق الثلاث عن ترتيب القراءة المسموح لزمن التشغيل بمعرفتها.
  • src/styles/locale/arabic.css هندسة نافذة القصّ، وبطانية التباعد، والعائلات ذات unicode-range، والقاعدة الوحيدة في الملف التي لم تُقيَّد عمدًا بالمستند العربي.
  • src/styles/components/site-nav.css إلغاء عكس الرأس واستعادة الاتجاهين المقابلة له، مع منطق إطفاء سبب واحد بدل سبعة أعراض.
  • src/styles/sections/projects-index.css المجموعة التي تنعكس بنفي خاصّية مخصّصة واحدة، وصيغة z-index المتروكة عمدًا، والعدّاد الذي لم ينل قاعدته قط.

مُراجَع مقابل

Alaa Abbod

بقلم

علاء عبّود

مطوّر إبداعي — هيرنه، ألمانيا

مصمّم ومطوّر يبني مواقع ويب سهلة الوصول وتطبيقات جوال ومتاجر إلكترونية وهويات بصرية كعملٍ واحد، وبيديه. هذا الموقع منشور بالإنجليزية والألمانية والعربية من مصدر واحد، ومن هناك جاء معظم هذه الأسئلة.

Alaa Abbod

هل النسخة العربية فكرة لاحقة في خارطة طريقك؟

غالبًا ما تكون كذلك، وغالبًا ما تكون أرخص بند في القائمة يمكن تقديمه. وإن كنت تخطّط لبناء بلغتين أو بثلاث، فقرارات الاتجاه — التحويلات، وترتيب التركيز، والتقسيم، ومقاييس الخط — تستحقّ الحسم قبل أن يتصلّب التخطيط حولها.

من فضلك أدر جهازك،
هذا الموقع مبني عموديًا.