Circular timeline progress bar UI

المكوّنات الصامدة: ما لا يُقلب في واجهات اليمين

|

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

عدد الكلمات: ~٢٣٠٠ · مدة القراءة: ١٢ دقيقة

المكوّنات الصامدة: ما لا يُقلب في واجهات اليمين

ليس كل قلب تصحيح — بعض العناصر تحمل معنى جهتها، وعكسها خطأ هندسي يُربك المستخدم لا يُسهّل عليه


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

في هذا المقال من منصة ذي يزن، نواصل رحلتنا مع سلسلة “دليل هندسة واجهات اليمين” عند نقطة تُربك كثيراً من المطورين: لقد أتقنا قلب الواجهة بالخصائص المنطقية، وأصبح التخطيط ينعكس تلقائياً مع تغيير الاتجاه. لكن ماذا نفعل حين ينقلب شيءٌ لا يجب أن ينقلب؟

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

لماذا توجد مكوّنات لا تُقلب

القاعدة التي أرسيناها في المقال الأول بسيطة: اجعل الواجهة تتبع اتجاه القراءة. ابدأ من اليمين في العربية، ومن اليسار في الإنكليزية. لكن بعض العناصر في الواجهة لا تعبّر عن “بداية نص وقراءة” — بل تعبّر عن اتجاه فيزيائي أو زمني له معنى مستقل عن اللغة.

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

الفرق بين المكوّن القابل للقلب والمكوّن الصامد ليس تقنياً — بل دلالي. السؤال الصحيح ليس “هل هذا العنصر يقع على اليسار؟” بل “هل جهة هذا العنصر تحمل معنى يخص الزمن أو الفيزياء أو اتفاقاً عالمياً؟” إذا كانت الإجابة نعم، فالعنصر صامد.

المكوّن الأول: مشغّلات الوسائط

مشغّل الصوت أو الفيديو هو أوضح مثالٍ على المكوّن الصامد. شريط التقدم فيه يمثّل محور الزمن: اليسار هو البداية (الثانية صفر)، واليمين هو النهاية (نهاية المقطع). هذا الاتفاق راسخٌ بعمقٍ في ذاكرة المستخدم العربي كما هو لدى غيره، فقد استخدم هذا النمط في كل مشغّل صوتٍ أو فيديو رآه في حياته.

عكس هذا الشريط يُنتج ارتباكاً حقيقياً:

  • يظن المستخدم أن التشغيل وصل ٩٠٪ وهو في الحقيقة عند ١٠٪.
  • حين يسحب المؤشر نحو اليمين بقصد التقديم، يجد نفسه يُرجع التشغيل للوراء.
  • أزرار التحكم (تشغيل، توقف مؤقت، صوت) التي تتبع ترتيباً متعارفاً عليه عالمياً تصبح مبعثرة.

الحل ليس تعطيل RTL عن المشغّل كاملاً، بل تعطيله عن شريط التقدم تحديداً مع الإبقاء على النص العربي والتسميات في اتجاههم الصحيح:

/* المشغّل يرث dir="rtl" من الصفحة */
.media-player {
  display: flex;
  flex-direction: column;
  /* النصوص والتسميات تبقى عربية — لا نتدخل */
}

/* شريط التقدم صامد: يُعطّل RTL بشكل صريح */
.media-player .progress-bar {
  direction: ltr;         /* الزمن يسير دائماً من اليسار */
  writing-mode: horizontal-tb;
}

/* الرقم الزمني (00:45 / 03:20) يبقى LTR أيضاً */
.media-player .time-display {
  direction: ltr;
  font-variant-numeric: tabular-nums;
  unicode-bidi: isolate;  /* عزل عن سياق RTL المحيط */
}

/* أزرار التحكم: ترتيبها ثابت، لكن تغيّر جهة كتلتها فقط */
.media-player .controls {
  /* flex-direction يبقى row — الترتيب الداخلي لا يتغير */
  /* يمكن محاذاة الكتلة ككل نحو اليمين في RTL */
  justify-content: flex-end;
}

لاحظ أننا لم نكتب [dir="rtl"] لعكس أي شيء، بل كتبنا direction: ltr داخل المكوّن لتثبيته. هذا هو جوهر المكوّن الصامد: لا نمنع RTL من الصفحة، بل نمنعه من عنصرٍ بعينه.

media player interface design

🔍 ملاحظةٌ رصدية — فيسبوك لايت (Facebook Lite)

يُلاحظ مستخدمو النسخة العربية من تطبيق “فيسبوك لايت” على أندرويد اختفاء شريط تقدم الفيديو وعجزهم عن سحب مؤشر الزمن، وهو سلوكٌ لا يزال قائماً حتى وقت كتابة هذه السطور. السبب المرجَّح هو تطبيق قلبٍ قسريٍ شاملٍ على مشغّل الوسائط دون استثناء شريط التقدم، مما يُخرج المؤشر خارج حدود الرؤية خلف الطبقات البصرية المقلوبة. تطبيق “لايت” بطبيعته يُخفّف الكود ويُقلّص الاستثناءات، وهذا المكوّن يبدو أنه سقط في تلك العملية. المفارقة أن المشغّل يعمل في النسخة الكاملة من التطبيق، مما يُرجّح أن الاستثناء موجودٌ هناك وغائب هنا.

المكوّن الثاني: شريط التقدم الدائري والمستطيل

أشرطة التقدم بشكلَيها الدائري والمستطيل تشترك في نفس المشكلة: فهي تعبّر عن نسبة اكتمال، لا عن اتجاه قراءة. ٧٥٪ مكتمل يعني نفس الشيء بالعربية والإنكليزية.

الشريط المستطيل (Linear Progress)

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

/* شريط تقدم صامد */
.progress-bar-track {
  direction: ltr;          /* يثبت اتجاه الامتلاء */
  width: 100%;
  height: 8px;
  background: #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-bar-fill {
  /* العرض يُحسب بالجافا سكريبت: style="width: 75%" */
  height: 100%;
  background: #c0392b;
  /* لا نستخدم margin-inline هنا — الشريط صامد */
  /* transform-origin يبقى على اليسار */
}

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

الشريط الدائري (Circular Progress)

الدائرة تُقلق بعض المطورين لأن الاتجاه فيها ليس خطياً. العرف العالمي — وهو ما تتبعه جميع المكتبات الكبرى — أن الدائرة تبدأ من الأعلى (الساعة ١٢) وتسير في اتجاه عقارب الساعة. هذا اتفاقٌ بصريٌ لا علاقة له بالقراءة.

/* دائرة SVG صامدة */
.circular-progress svg {
  /* لا نقلبها بـ transform: scaleX(-1) */
  /* ولا نغيّر stroke-dashoffset في RTL */
  /* الدوران في اتجاه عقارب الساعة ثابت */
}

/* إذا كان النص بداخلها: النص يرث RTL بشكل طبيعي */
.circular-progress .label {
  /* لا تدخّل — يرث dir من الصفحة */
  text-anchor: middle;
}

القاعدة البسيطة: شكل الدائرة لا يتغير، لكن النص بداخلها يتبع اتجاه الصفحة.

Circular timeline progress bar UI

المكوّن الثالث: المخططات الزمنية

المخطط الزمني (Timeline) هو الحالة الأكثر حساسيةً في هذا الموضوع، لأن فيها توتراً حقيقياً بين منطقين متعارضين:

  • المنطق الزمني: الزمن يسير من الماضي إلى المستقبل. في معظم التمثيلات البصرية العالمية، هذا يعني من اليسار إلى اليمين.
  • المنطق الثقافي: القارئ العربي يبدأ من اليمين. إذا وضعت أقدم حدث على اليسار، سيقرأه بعد أحدث الأحداث.

لا يوجد جوابٌ واحدٌ صحيحٌ هنا، بل يعتمد على طبيعة المخطط:

نوع المخطط الزمني القرار الموصى به السبب
سيرة ذاتية أو تاريخ شركة اقلبه مع RTL المستخدم يقرأه كنص — الأقدم يكون على اليمين
خط زمني لمشروع (Gantt) أبقِه LTR الزمن يسير للأمام — الفرق البصري أهم من اللغة
خط تقدم خطوات (Stepper) اقلبه مع RTL يمثّل تسلسلاً إجرائياً — يتبع منطق القراءة
مخطط بياني زمني (Chart) أبقِه LTR محور الزمن X اتفاق علمي — عكسه يُخطئ القراءة

المعيار الفاصل: هل المستخدم يقرأ المخطط أم يحلّله؟ القراءة تتبع اللغة. التحليل يتبع الاتفاق العلمي والبصري.

المكوّن الرابع: الأسهم والأيقونات ذات الاتجاه

الأسهم هي الفخ الأكثر شيوعاً في تصميم واجهات RTL، لأنها تنقسم إلى فئتين يسهل الخلط بينهما:

أسهم يجب قلبها ✓

كل سهمٍ يعبّر عن اتجاه التنقل في الواجهة — للأمام، للخلف، فتح قائمة، طيّ قائمة — يجب أن يُقلب مع RTL:

  • سهم “التالي” في الترقيم: يشير لليسار في LTR، ولليمين في RTL.
  • سهم فتح قائمةٍ منسدلة: يشير للأسفل (لا يتغير)، أو يشير للجانب وهنا يُقلب.
  • سهم “رجوع” (Breadcrumb): يشير لليسار في LTR، ولليمين في RTL.

أسهمٌ يجب إبقاؤها صامدة ✗

كل سهمٍ يعبّر عن مفهومٍ فيزيائيٍ أو بصريٍ ثابتٍ لا علاقة له بالتنقل:

  • أيقونات الوسائط: ▶ تشغيل، ⏮ رجوع للبداية، ⏭ قفز للنهاية، هذه رموزٌ عالميةٌ موحّدة.
  • أسهم الرسوم البيانية التي تعبّر عن نموٍ أو انخفاض.
  • السهم في واجهات الخرائط الذي يشير لاتجاه الشمال.
/* سهم التنقل — يُقلب */
.nav-arrow-next {
  /* في LTR: →  في RTL: ← */
  /* باستخدام CSS Logical Properties ينقلب تلقائياً */
  /* أو بـ transform صريح إذا كان SVG */
}

[dir="rtl"] .nav-arrow-next svg {
  transform: scaleX(-1);   /* عكس السهم الأفقي */
}

/* أيقونة تشغيل — صامدة */
.play-icon {
  /* لا transform، لا scaleX */
  /* ▶ تبقى ▶ دائماً */
}

/* طريقة أذكى: استخدام أيقونات "منطقية" في المكتبات الحديثة */
/* مثال مع lucide-react */
/*  تُقلب تلقائياً في RTL بعض المكتبات */
/*  لا تُقلب أبداً */

كيف تقرر: إطار عمل للحكم على أي مكوّن

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

السؤال الأول — هل المكوّن يمثّل محور الزمن أو الكم؟

إذا كان يعبّر عن مرور وقت، نسبة اكتمال، أو كميةٍ مقاسةٍ (شريط تقدم، مشغّل صوت، مخططٌ بياني) ← على الأرجح صامد.

السؤال الثاني — هل اتجاهه اتفاقٌ عالميٌ متجذّرٌ في الذاكرة البصرية؟

أيقونات الوسائط، إشارات الخطر، المقاييس العلمية، الخرائط  ← صامد قطعاً. تغييره يُشوّش لا يُسهّل.

السؤال الثالث — هل المستخدم سيقرأه كنص أم يتفاعل معه كأداة؟

إذا كان يُقرأ (خطوات، سيرة ذاتية، ترقيم) ← اقلبه. إذا كان يُستخدم كأداةٍ بصرية (لوحة تحكم، مخطط، مشغّل) ← أبقِه.

الهدف من هذا الإطار ليس أتمتة القرار، بل تحويله من قرارٍ تقنيٍ (“هل أُضيف scaleX(-1)؟”) إلى قرارٍ دلالي (“ماذا يعني هذا المكوّن للمستخدم؟”). المعنى يأتي أولاً، الكود يتبع.

تنفيذ الصمود: الأدوات المتاحة

حين تقرر أن مكوّناً صامدٌ، لديك ثلاث أدوات لتنفيذ ذلك في الكود:

الأداة الأولى — direction: ltr الصريح

الأبسط والأوضح: تكتب direction: ltr مباشرةً على المكوّن. يُلغي الإرث من الصفحة. يناسب الحاويات الكاملة كمشغّل الوسائط.

الأداة الثانية — unicode-bidi: isolate

لا تغيّر الاتجاه، بل تعزل المكوّن عن سياق بيدي المحيط. هذا مفيدٌ حين تريد أن يعتمد المكوّن على اتجاهه الداخلي دون تأثير الصفحة. استخدمناها في المقال الأول للأرقام الزمنية.

الأداة الثالثة — transform: scaleX(-1)

لقلب أيقونة SVG أو صورةٍ بشكلٍ بصريٍ فقط دون تغيير اتجاه التدفق. تُستخدم لأسهم التنقل في RTL حين يكون الأصل سهماً يشير لليمين وتريده أن يشير لليسار. لا تُستخدم على مكوّنات الزمن أو الكم.

/* ملخّص الأدوات الثلاث */

/* ١ — تثبيت الاتجاه: للحاويات الكاملة */
.media-player .progress-bar {
  direction: ltr;
}

/* ٢ — عزل بيدي: للعناصر المضمّنة */
.time-code {
  unicode-bidi: isolate;
  direction: ltr;
}

/* ٣ — قلب بصري: للأيقونات في سياق RTL */
[dir="rtl"] .nav-chevron-right {
  transform: scaleX(-1);
}

/* ما لا تفعله أبداً: قلب مشغّل الوسائط كاملاً */
/* [dir="rtl"] .media-player { transform: scaleX(-1); } ← خطأ */

خلاصةٌ وما يلي

الواجهة الجيدة في RTL ليست الواجهة التي قُلب فيها كل شيء، بل التي قُلب فيها ما يستحق القلب وصمد فيها ما يجب أن يصمد. الخلط بين النوعين هو مصدر معظم الأخطاء البصرية التي نراها في المواقع العربية اليوم.

القاعدة التي بنيناها اليوم: المكوّن الذي يعبّر عن الزمن أو الكم أو اتفاقاً عالمياً بصرياً، صامد. أما المكوّن الذي يعبّر عن اتجاه التنقل أو ترتيب القراءة، قابل للقلب. وحين تشك، اسأل: ماذا يعني هذا العنصر للمستخدم؟ المعنى يُحدد الاتجاه، لا العكس.

في المقالَين الأول والثاني تناولنا آلية القلب وحدوده. لكننا لم نسأل بعد السؤال الأعمق: كيف يقرأ المستخدم العربي الشاشة أصلاً؟ هل يسير بصره في نمطٍ يختلف عن نظيره الغربي؟ وكيف يؤثر ذلك على موضع أزرار اتخاذ القرار؟ هذا ما يجيب عنه المقال الثالث: علم النظر.


المراجع والمصادر:

  1. إرشادات Material Design لدعم ثنائية الاتجاه: Material Design — Bidirectionality
  2. دليل Apple لتصميم واجهات RTL: Apple HIG — Right to Left
  3. إرشادات W3C لتوطين الويب: W3C Internationalization — Authoring HTML
  4. مقالنا السابق في هذه السلسلة: قلب الواجهة: الخصائص المنطقية في CSS

— دليل هندسة واجهات اليمين —

المقال السابق: ١- قلب الواجهة: الخصائص المنطقية في CSS

المقال الحالي: ٢- المكوّنات الصامدة: ما لا يُقلب في واجهات اليمين

المقال التالي: ٣- علم النظر: كيف يقرأ المستخدم العربي الشاشة

سلاسل مشابهة:
دليل معالجة النصوص الهجينة | دليل معايرة البيانات المالية | ورشة التوطين لتطبيقات الويب ٣.٠ والذكاء الاصطناعي

منصة ذي يزن © ٢٠٢٦

سلاسل التوطين

دليل هندسة واجهات اليمين — ٤ مقالات

المقالة 1
١ / ٤

قلب الواجهة: الخصائص المنطقية في CSS

لماذا لا يكفي dir=”rtl” وحده، وكيف تحل الخصائص المنطقية مشكلة قلب الواجهة من أساسها.

المقالة 2
٢ / ٤

المكوّنات الصامدة: ما لا يُقلب في واجهات اليمين

مشغّلات الوسائط والمخططات الزمنية والأسهم — لماذا عكسها خطأ هندسي لا تصحيح.

المقالة 3
٣ / ٤

علم النظر: كيف يقرأ المستخدم العربي الشاشة

نمط F المعكوس وخرائط الحرارة وتأثير مسار البصر على موضع أزرار اتخاذ القرار.

المقالة 4
٤ / ٤

مشروع التدقيق: إصلاح واجهة قُلبت بشكل خاطئ

مشروع تطبيقي ختامي: تشريح ثلاثة عشر خطأ في واجهة مُقلَّبة وإصلاحها كوداً بكود.

سلسلة دليل هندسة واجهات اليمين — ٤ مقالات  |  منصة ذي يزن © ٢٠٢٦

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *