اذهب إلى المحتوى

التركيز على عناصر صفحة الويب


Bassel Alkhatib

نُناقش مسألة التركيز Focus في القسم الأول من هذه المقالة التعليمية، كما نشرح آلية ترتيب عناصر شجرة DOM في القسم الثاني منها، ونُنهي المقالة بشرح استخدام فهرس الجدولة tabindex.

مقدمة في التركيز

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

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

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

ما هو التركيز

يُحدّد التركيز عنصر التحكم الحالي الذي يتلقى الإدخالات من لوحة المفاتيح ويعرض الأحرف التي يكتبها المستخدم، كما يستقبل هذا العنصر بيانات أي عملية لصق من الحافظة.

001TextBox.png

يُميّز العنصر الحاصل على التركيز بواسطة إطار لوني حوله يعتمد نمطه على المستعرض أو على أسلوب التنسيق المُحدّد من قبل مطور صفحة الويب. يقوم المستعرض Chrome مثلًا بوضع إطار أزرق، بينما يقوم Firefox بوضع إطار متقطع.

002Button.png

يتعامل بعض المستخدمين مع حاسوبهم حصرًا باستخدام لوحة المفاتيح وبالتالي يكون التركيز بالنسبة لهم أمرًا هامًا جدًا فهو وسيلتهم للوصول إلى أي كائن في صفحة الويب. تنص قائمة التحقق من مجموعة إمكانية الوصول Web AIM (اختصارًا إلى Web Accessibility In Mind) في الفقرة السابقة منها على أن جميع وظائف صفحة الويب يجب أن تكون ممكنة الوصول عن طريق لوحة المفاتيح (إلا في حالات خاصة لا يُمكن القيام بها باستخدام لوحة المفاتيح كالرسم اليدوي مثلًا).

يُمكن نقل التركيز من عنصر لآخر باستخدام مفتاح الجدولة Tab أو التركيب Shift+Tab أو باستخدام مفاتيح الأسهم. يختلف هذا الأسلوب قليلًا في نظام التشغيل Mac OSX. يسمح لك المتصفح Chrome بالتنقل باستخدام المفتاح Tab بينما يجب استخدام Option+Tab في المتصفح Safari. يُمكن تغيير إعدادات نقل التركيز باستخدام لوحة المفاتيح عن طريق نافذة لوحة المفاتيح من تفضيلات النظام:

003Preferences.png

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

تعريف إمكانية التركيز

يُمكن التركيز على أي عنصر من عناصر HTML التي تسمح للمستخدم بالتفاعل معها (تغيير قيمها أو حالتها) مثل صناديق النصوص والأزرار والقوائم، وتدخل تلقائيًا في ترتيب الجدولة وتتفاعل مع أحداث لوحة المفاتيح دون أي تدخل من قبل مطور الصفحة.

004focusable (1).png

أما العناصر التي لا يتفاعل المستخدم معها مثل الفقرات والحاويات div فلا ينتقل التركيز عليها ولا تدخل في ترتيب الجدولة.

005notfocusable (1).png

تجربة التركيز

نعرض في المثال التالي تقانات التركيز التي شرحناها سابقًا: افتح المستعرض Chrome وانتقل للرابط airline site mockup page واطلب تذكرة سفر باستخدام لوحة المفاتيح حصرًا (لا تتفاعل الصفحة بأي حال مع الفأرة).

006airlinesite.png

عليك ملء المعلومات التالية:

  • اتجاه واحد للسفر oneway
  • إلى مدينة Arrival ملبورن Melbourne
  • تاريخ المغادرة Depart Date 12/10/2017
  • تاريخ العودة Return Data 23/10/2017
  • مقعد جانب النافذة Preferred seat type
  • لا تطلب تلقي إشعارات العروض الترويجية Receive promotional offers

بمجرد أن تنتهي من إتمام عملية إدخال البيانات دون أي خطأ ومن ثم نقر زر البحث، سيتم مسح البيانات وإعادة تهيئة نموذج إدخال جديد (قم بالتجربة المطلوبة ومن ثم أتمم القراءة).

لنعاين الآن كيف يتفاعل نموذج الصفحة السابق مع إدخالات لوحة المفاتيح. يؤدي الضغط على مفتاح الجدولة Tab في البداية إلى إضاءة الروابط أعلى النموذج (الرحلات Flights، الفنادق Hotels، سيارات الأجرة Rental Cars)، وإذا استمريت بضغط مفتاح الجدولة مرارًا ستنتقل إلى مجموعة أزرار الانتقاء والتي عليك الآن استخدام مفاتيح الأسهم للتنقل فيما بينها (نوع الرحلة). اخرج من مجموعة أزرار الانتقاء باستخدام مفتاح الجدولة Tab لتنتقل إلى حقل الاسم ومن ثم إلى حقل العنوان للكتابة فيهما. عند وصولك للقائمة المنسدلة للمدن، يُمكنك اختيار عنصر منها عن طريق مفاتيح الأسهم أو عن طريق البدء بكتابة الأحرف الأولى من اسم المدينة ليتم ملء الحقل بالمدينة المناسبة. عند وصولك لقائمة نوع الكرسي يُمكن اختيار عنصر من القائمة باستخدام مفاتيح الأسهم أو بكتابة أحد الأحرف w أو a أو n لتحديد عنصر القائمة الموافق (لا تفضيل No preference، ممر Aile، نافذة Window). يُمكنك إلغاء تحديد صندوق التحقق (لطلب عدم تلقي إشعارات الحملات الترويجية) بالضغط على مفتاح المسافة عند وصول التركيز لصندوق التحقق. ضع أخيرًا التركيز على زر البحث Search وانقر المفتاح Enter لإرسال بيانات النموذج.

يبدو أن التفاعل مع النموذج باستخدام لوحة المفاتيح فقط أسهل وأسرع من استخدام الفأرة ولوحة المفاتيح معًا (وضياع الوقت بالتنقل بينهما)، وهو أمر سهل التحقيق من قبل المطور لأن ما عليه سوى استخدام عناصر HTML الأساسية ولن يحتاج إلى كتابة أي شيفرة إضافية لإدارة عمليات التركيز.

أهمية ترتيب العناصر في شجرة DOM

يؤدي استخدام عناصر HTML الأساسية إلى الحصول على ترتيب انتقال تركيز ملائم إذ أن ترتيب الانتقال بين العناصر يكون وفق ترتيبها في نموذج كائن الوثيقة DOM.

يكون ترتيب انتقال التركيز بين الأزرار في المثال التالي وفق ترتيبها في DOM أي الزر "I Should" أولًا ومن ثم الزر "Be Focused" و أخيرًا الزر "Last":

<button>I Should</button>
<button>Be Focused</button>
<button>Last!</button>

يجب الانتباه إلى بعض المشاكل التي قد تنجم عند استخدام تنسيق CSS لاسيما إذا كان ذلك يؤثر على أمكنة تموضع العناصر. فمثلًا إذا وضعت الخاصية (عائم إلى اليمين) للزر الأول "float: right" فسيظهر هذا الزر أقصى اليمين إلا أن ترتيبه في الجدولة سيبقى الأول لأنه الأول في ترتيب العناصر ضمن DOM. بالتأكيد، سيُسبب هذا إرباكًا للمستخدم إذ سيقفز بزر الجدولة Tab من الزر أقصى اليمين "I Should" إلى الزر أقصى اليسار "Be Focused" بعده.

<button style="float: right">I Should</button>
<button>Be Focused</button>
<button>Last!</button>

تنص قائمة التحقق من مجموعة إمكانية الوصول Web AIM اختصارًا Web Accessibility In Mind على أن الترتيب المرئي (ترتيب القراءة) يجب أن يكون متوافقًا مع ترتيب الجدولة كي لا نُربك المستخدم الذي يعتمد على لوحة المفاتيح.

المحتوى غير الظاهر

يجب الانتباه إلى انتقال التركيز على عناصر غير ظاهرة مما يُربك المستخدم الذي سيشعر عندها بفقدان أو ضياع مؤشر التركيز وسيبدأ بضغط مفتاح الجدولة مرارًا ليكتشف أن مؤشر التركيز يظهر ويختفي! يُمكن أن تظهر هذه المشكلة مثلًا عند استخدام لوحة تنقل جانبية متجاوبة responsive side navigation panel وعندها يجب أن نمنع التركيز من الانتقال للوحة عندما لا تكون ظاهرة، ونسمح له بالانتقال لها فقط عندما يكون المستخدم في حالة تفاعل معها.

009navpanel.png

قد يتوجب عليك أحيانًا البحث عن موضع التركيز باستخدام خاصية العنصر النشط document.activeElement لمعرفة العنصر النشط حاليًا، ومن ثم إظهاره باستخدام display: none أو visibility: hidden أو إخفائه باستخدام display: block أو visibility: visible حسب الحالة.

010visiblehidden.png

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

استخدام فهرس الجدولة tabindex

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

يُمكن تحديد ترتيب الجدولة لأي عنصر باستخدام السمة tabindex والتي تكون قيمتها عدد صحيح يُحدّد ترتيب العنصر. علاوةً على ذلك، يُمكن استخدام هذه السمة لإضافة كائن لا يتمتع بإمكانية التركيز (مثل الحاويات div) إلى ترتيب الجدولة، كما يُمكن حذف عناصر من ترتيب الجدولة.

يؤدي إسناد القيم 0 إلى السمة tabindex لإضافة العنصر إلى الترتيب الطبيعي للجدولة أي يُمكن الانتقال له باستخدام مفتاح الجدولة Tab كما يُمكن وضع التركيز عليه برمجيًا باستخدام الطريقة focus. يُظهر المثال التالي عنصر مخصص يُمكن الانتقال له باستخدام المفتاح Tab:

<custom-button tabindex="0">Press Tab to Focus Me!</custom-button>

يؤدي إسناد القيم -1 إلى السمة tabindex إلى إزالة العنصر من الترتيب الطبيعي للجدولة أي لن يعود بالإمكان الانتقال له بمفتاح الجدولة Tab إلا أنه يُمكن وضع التركيز عليه برمجيًا باستخدام الطريقة focus.

<button id="foo" tabindex="-1">I'm not keyboard focusable</button>
<button onclick="foo.focus();">Focus my sibling</button>

لا يُمكن الآن الانتقال للزر الأيسر بمفتاح الجدولة Tab وإنما يُمكن وضع التركيز عليه بالنقر على الزر الأيمن:

يؤدي إسناد قيمة صحيحة أكبر من الصفر (مثلًا 5) إلى وضع العنصر الموافق في مقدمة ترتيب الجدولة. أما إذا وجد أكثر من عنصر لهم قيمة أكبر من الصفر فيتم الانتقال بدءًا من العنصر ذو القيمة الأدنى (أكبر من الصفر) إلى القيمة الأعلى التالية وهكذا. تُعدّ عملية إسناد قيم أكبر من الصفر مخالفة للنموذج النمطي الطبيعي anti-pattern.

ليكن لدينا مثلًا:

<button>I should be first</button>
<button tabindex="6">And I should be second</button>
<button tabindex="5">But I jumped to the front!</button>

سيكون الزر الأخير (الأيمن) أول الأزرار في الجدولة ومن ثم الزر الثاني(الأوسط) وأخيرًا الزر الأول.

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

لا تقلق بشأن مستخدمي قارئ الشاشة أن يفوتهم محتوى هامًا بسبب أن ليس له ترتيب جدولة tabindex، فحتى لو كان المحتوى مهمًا مثل الصور لا داع أن تضع له ترتيب جدولة لأن المستخدم لن يتفاعل معها أصلًا. ركّز على وضع عبارات توصيفية للصور في الخاصية Alt كي يستفيد منها مستخدمي قارئ الشاشة كما سنعرض لاحقًا.

إدارة التركيز على مستوى الصفحة

يُمكن أن يكون استخدام السمة ضروريًا في بعض الحالات. مثلًا: إذا احتوت صفحة على عدة أقسام لا تُعرض جميعها بنفس الوقت أي أن النقر على رابط قد يؤدي إلى تغيير المحتوى الظاهر دون إعادة تحميل الصفحة. يجب إذًا في هذه الحالة إسناد القيمة -1 لترتيب الجدولة لكل قسم كي لا ننتقل بمفتاح الجدولة Tab للقسم وإنما حصرًا باستخدام الطريقة focus. يحافظ هذا الأسلوب، المدعو بإدارة التركيز، على تزامن المحتوى المرئي مع سياق تفاعل المستخدم مع الصفحة.

إدارة التركيز للعناصر المخصصة

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

نقوم في الشيفرة التالية باستخدام عنصر القائمة الأساسي مما يُعطي قائمة يُمكن التنقل والاختيار منها باستعمال مفاتيح الأسهم:

<!-- يُمكن نقل التركيز باستخدام مفتاح الجدولة أو مفاتيح الأسهم-->
<select>
  <option>Aisle seat</option>
  <option>Window seat</option>
  <option>No preference</option>
</select>

قد لا يكون من السهل دائمًا معرفة سلوك لوحة المفاتيح الواجب تنفيذها مما يتوجب العودة إلى دليل تطوير تطبيقات الإنترنت الغنية سهلة الوصول Accessible Rich Internet Applications Authoring Practices التي تختصر إلى ARIA، لمعاينة قائمة أنواع عناصر التحكم وأحداث لوحة المفاتيح التي تتجاوب معها. نستخدم هذا الدليل لدعم لوحة المفاتيح في عنصر مخصص جديد. ليكن مثلًا العنصر المخصص Custom Elements الجديد التالي والذي يُماثل مجموعة أزرار الانتقاء إنما يُمكن أن نُخصص له مظهرًا وسلوكًا جديدين:

<radio-group>
  <radio-button>Water</radio-button>
  <radio-button>Coffee</radio-button>
  <radio-button>Tea</radio-button>
  <radio-button>Cola</radio-button>
  <radio-button>Ginger Ale</radio-button>
</radio-group>

بمراجعة القسم الثاني من دليل ARIA لتحديد نوع التفاعل مع لوحة المفاتيح المطلوب، نجد ضمن قائمة نماذج التصميم المقترحة جدول مواصفات مجموعة أزرار الانتقاء characteristics table for radio groups والتي تُعدّ الأقرب للعنصر المخصص الذي نقوم بتطويره. يُبين هذا الجدول ضرورة تجاوب العنصر مع مفاتيح الأسهم أعلى/أسفل/يمين/يسار. لإضافة هذا التفاعل مع العنصر المخصص الجديد سنستخدم تقنية تُدعى ترتيب الجدولة المتنقل roving tabindex.

015ARIA.png

تتمحور تقنية ترتيب الجدولة المتنقل على إسناد القيمة -1 لجميع العناصر ما عدا العنصر المُحدّد حاليًا:

<radio-group>
  <radio-button tabindex="0">Water</radio-button>
  <radio-button tabindex="-1">Coffee</radio-button>
  <radio-button tabindex="-1">Tea</radio-button>
  <radio-button tabindex="-1">Cola</radio-button>
  <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

يستخدم العنصر المخصص الجديد مستمع listener لمعرفة المفتاح الذي يضغطه المستخدم وعندها تُسندّ قيمة ترتيب الجدولة -1 إلى العنصر المُحدّد حاليًا ومن ثم تُسندّ القيمة 0 لترتيب الجدولة للعنصر الجديد الذي سيُحدّد باستخدام الطريقة focus.

<radio-group>
  // Assuming the user pressed the down arrow, we'll focus the next available child
  <radio-button tabindex="-1">Water</radio-button>
  <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
  <radio-button tabindex="-1">Tea</radio-button>
  <radio-button tabindex="-1">Cola</radio-button>
  <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

عندما يصل المستخدم إلى الخيار الأخير (أو الأول، وفق الاتجاه الذي يتحرك به باستخدام مفاتيح الأسهم)، نعاود وضع التركيز على الخيار الأول (أو الأخير).

يُمكن العودة إلى مستودع GitHub للحصول على الشيفرة المتاح للعموم وتجريب العنصر الجديد المخصص.

النوافذ الشرطية وقفل لوحة المفاتيح

 

يُمكن في بعض الأحيان، أثناء إدارة التركيز، الوقوع في ورطة لا يُمكن الخروج منها. من الأمثلة على ذلك حالة عنصر الإكمال التلقائي autocomplete الذي يحاول إدارة التركيز ومتابعة ترتيب الجدولة إلا أنه يمنع التركيز من الخروج منه حتى إكمال النص مما يؤدي إلى حجز لوحة المفاتيح والذي يُمكن أن يضايق المستخدم إلى حد كبير. تنص الفقرة 2.1.2 من دليل ARIA على أنه لا يجوز بأي حال من الأحوال حجز لوحة المفاتيح أو حصر التركيز في عنصر ما إذ أن المستخدم يجب أن يكون قادرًا على التنقل ضمن جميع عناصر الصفحة بحرية كاملة.

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

017Modal.png

يُمكن في مثل هذه الحالات تنفيذ حجز مؤقت للوحة المفاتيح لحصر التركيز ضمن النافذة الشرطية عندما تكون مفتوحة ومن ثم العودة للعنصر الذي كان عليه التركيز في الصفحة الخلفية عند إغلاق النافذة الشرطية.

يوجد العديد من المقترحات لتسهيل المعالجة السابقة مثل استخدام العنصر الجديد <dialog> إلا أنه مازال غير متوافق مع بعض المتصفحات. يُمكن العودة للمقالة للتزود بمعلومات أكثر عن <dialog> كما يُمكن تفحص هذا المثال من مستودع GitHub.

نعرض فيما يلي الخطوات الأساسية اللازمة لتنفيذ قفل لوحة المفاتيح بشكل مؤقت وذلك لحالة نافذة شرطية (حاوية div لبعض العناصر) مع حاوية ثانية للغطاء الداكن.

  1. استخدم التابع document.querySelector لحفظ مرجع لحاوية النافذة الشرطية ومرجع للحاوية الثانية.
  2. احفظ فور فتح النافذة الشرطية مرجع للعنصر الذي كان عليه التركيز في النافذة الخلفية (وبهذا ستتمكن من الرجوع إليه لاحقًا).
  3. استخدم مستمع لحدث ضغط مفتاح للأسفل keydown. يجب أيضًا استخدام مستمع لحدث النقر على الحاوية الثانية.
  4. احصر مجموعة العناصر القابلة للتركيز في النافذة الشرطية إذ سيلعب العنصر الأول والأخير دور الحارس للدوران ضمن مجموعة العناصر مع مفتاح الجدولة لضمان البقاء ضمن النافذة الشرطية.
  5. أظهر النافذة الشرطية وضع التركيز على أول عنصر فيها.
  6. انقل التركيز من عنصر لآخر للأمام عندما يقوم المستخدم بضغط مفتاح الجدولة Tab أو للخلف عندما يقوم المستخدم بضغط Shift+Tab مع مراعاة الدوران عند أول وآخر عنصر.
  7. أغلق النموذج حال ضغط المستخدم لمفتاح الهروب Esc (هذا أمر ضروري يسمح للمستخدم بإغلاق النافذة دون البحث عن زر الإغلاق ومفيد بالأخص للمستخدمين الذين لا يستعملون الفأرة).
  8. أخف النافذة الشرطية وحاوية الغطاء عند طلب الإغلاق وأعد التركيز على عنصر الصفحة الذي قمت بحفظ مرجع له.

يُمكن، باتباع الخطوات السابقة، إدارة نافذة شرطية مريحة التعامل لجميع فئات المستخدمين.

يُمكن الحصول على الشيفرة المتاح للجميع واختبار المثال كاملًا.

ترجمة -وبتصرف- للمقالات الثلاث التالية:

للمؤلفين الثلاثة: Meggin Kearney, Dave Gash, Rob Dodson.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...