معايير نجاح WCAG · Level AAA

WCAG 2.5.6: آليات الإدخال المتزامنة

يتطلب المعيار WCAG 2.5.6 ألا يقيّد محتوى الويب المستخدمين بنمط إدخال واحد عندما تكون آليات إدخال متعددة متاحة على المنصة، مما يضمن أن يتمكن الأشخاص من التبديل بحرية بين اللمس ولوحة المفاتيح والفأرة والصوت وغيرها من طرق الإدخال دون فقدان إمكانية الوصول إلى الوظائف.

  • Level AAA

ماذا يعني هذا المعيار

\n

WCAG 2.5.6 — آليات الإدخال المتزامنة هو معيار نجاح من المستوى AAA ضمن WCAG 2.2. المطلب الأساسي فيه مباشر: يجب ألا يقيّد محتوى الويب أو يتداخل مع قدرة المستخدم على استخدام آليات إدخال متعددة في الوقت نفسه أو بالتبادل. عملياً، يعني هذا أن صفحة الويب أو التطبيق لا يمكنه اكتشافياً (برمجياً) تحديد جهاز الإدخال الذي يستخدمه المستخدم حالياً ثم حبسه في تلك الطريقة الواحدة، وحرمانه من الوصول إلى طرق الإدخال الأخرى المتاحة.

\n

تدعم الأجهزة الحديثة مجموعة غنية من آليات الإدخال: لوحات مفاتيح مادية، فأرات ولوحات لمس، شاشات لمس، أقلام رقمية، أدوات تحكم بالمفاتيح (switch controls)، إدخال صوتي، تتبع العين، وغير ذلك. يعتمد العديد من المستخدمين على أكثر من واحدة من هذه الآليات في الوقت نفسه — على سبيل المثال، قد ينتقل مستخدم حاسوب محمول مزوّد بشاشة لمس بسلاسة بين لوحة اللمس وواجهة اللمس بالأصابع. قد يتنقل مستخدم متمرس في نموذج باستخدام لوحة المفاتيح بينما يستخدم الفأرة للتمرير. قد يستخدم شخص لديه إعاقة حركية مزيجاً من مؤشر للرأس وجهاز تبديل (switch). يحمي هذا المعيار جميع هذه أساليب العمل.

\n

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

\n

يحدث اجتياز عندما يمكن للمستخدمين التفاعل مع أي وجميع آليات الإدخال المتاحة في أي وقت أثناء تفاعلهم. يجب أن يستجيب المحتوى بشكل صحيح لأي آلية إدخال يختار المستخدم استخدامها في أي لحظة دون الحاجة إلى إعادة تحميل الصفحة أو تبديل وضع أو أي إجراء إضافي من المستخدم لإعادة تمكين نوع إدخال ما.

\n

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

\n

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

\n\n

لماذا يهم

\n

حرية استخدام آليات إدخال متزامنة أو قابلة للتبادل ليست ميزة للراحة — إنها متطلب حرج لإمكانية الوصول يؤثر مباشرة في عدة مجموعات مميزة من المستخدمين.

\n

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

\n

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

\n

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

\n

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

\n

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

\n

من منظور قابلية الاستخدام وتحسين محركات البحث (SEO)، يرتبط احترام آليات الإدخال المتزامنة بنتائج أفضل في Core Web Vitals، ومعدلات ارتداد أقل، ورضا أعلى للمستخدمين عبر فئات الأجهزة المتنوعة — وكلها إشارات تكافئها محركات البحث.

\n\n

قواعد Axe-core ذات الصلة

\n

يتطلب WCAG 2.5.6 اختباراً يدوياً — لا توجد قاعدة آلية في axe-core يمكنها اكتشاف جميع انتهاكات هذا المعيار بشكل موثوق. السبب جوهري: يمكن للأدوات الآلية فحص DOM وCSS الثابتين، ويمكنها اكتشاف أنماط JavaScript معينة، لكنها لا تستطيع مراقبة سلوك وقت التشغيل لمعالجات الأحداث بالكامل أثناء استجابتها لطرق إدخال مختلفة خلال جلسة مستخدم فعلية. غالباً ما يكون قرار تقييد آلية إدخال ما مشفراً في منطق التطبيق الذي لا يُنفّذ إلا استجابةً لأحداث محددة، مما يجعل التحليل الثابت غير كافٍ.

\n
    \n
  • لا توجد قاعدة آلية مخصصة في axe-core لـ 2.5.6. لا يقدّم axe-core قاعدة تتحقق تحديداً من قيود آليات الإدخال المتزامنة، لأن الانتهاك يظهر كسلوك JavaScript ديناميكي وليس كمسألة بنيوية في HTML أو ARIA. يمكن لصفحة أن تجتاز جميع فحوصات axe الآلية ومع ذلك تنتهك 2.5.6 إذا كانت معالجات الأحداث فيها تزيل أو تعطل آليات الإدخال برمجياً أثناء وقت التشغيل.
  • \n
  • أحداث المؤشر واكتشاف أحداث اللمس: بينما لا يمكن لـ axe-core التقاط التقييد نفسه، يجب على المدققين اليدويين البحث عن JavaScript يستمع لأحداث touchstart أو pointerdown ثم يعدّل DOM أو يزيل إدارة التركيز أو يضبط أعلاماً تغيّر سلوك لوحة المفاتيح. وبالمثل، فإن مستمعي keydown الذين يطلقون تغييرات في فئات CSS تخفي أهداف اللمس هي إشارات تحذيرية يجب فحصها يدوياً.
  • \n
  • لماذا تقصر الأتمتة: تحلل الماسحات الآلية المستند في لحظة زمنية معينة. قيود آليات الإدخال مشروطة — فهي تُفعّل فقط بعد إطلاق حدث إدخال محدد. لا يمكن للماسح الذي يعمل قبل تفاعل المستخدم أن يرى أن معالج touchstart سيستدعي لاحقاً document.querySelectorAll('[tabindex]').forEach(el => el.setAttribute('tabindex', '-1')) ويدمّر فعلياً التنقل بلوحة المفاتيح. لا يمكن إلا لمختبِر بشري يمارس طريقتي الإدخال بالتسلسل اكتشاف هذا الفشل.
  • \n
\n\n

كيفية الاختبار

\n
    \n
  1. فحص آلي أساسي: شغّل axe DevTools أو Lighthouse على الصفحة لإنشاء خط أساس والتقاط أي مشكلات متزامنة. رغم أن أياً من الأداتين لا يحتوي على قاعدة مخصصة لـ 2.5.6، قد تشير فحوصات أفضل الممارسات في axe DevTools إلى مصائد لوحة المفاتيح أو مشكلات إدارة التركيز التي تعد أعراضاً لتقييد الإدخال. دوّن أي حالات فشل لمعالجتها إلى جانب الفحوصات اليدوية أدناه.
  2. \n
  3. فحص مصدر JavaScript ومستمعي الأحداث: افتح Chrome DevTools، وانتقل إلى لوحة Elements، واستخدم جزء Event Listeners لفحص ما إذا كانت مستمعات touchstart أو pointerdown أو pointermove أو MSPointerDown مرفقة بالمستند أو body. في وحدة التحكم (Console)، ابحث في مصدر JavaScript للصفحة عن أنماط مثل ontouchstart in window أو navigator.maxTouchPoints أو 'pointer' in navigator مع تعديلات على DOM. هذه تقنيات شائعة تُستخدم لاكتشاف طريقة الإدخال وتقييد الوظائف.
  4. \n
  5. اختبار تفاعل متعدد الأنماط (لوحة مفاتيح + لمس): على جهاز يدعم كلاً من الإدخال باللمس ولوحة المفاتيح (مثل Surface أو iPad مع لوحة مفاتيح أو حاسوب محمول بشاشة لمس)، ابدأ في التنقل في الصفحة باستخدام لوحة المفاتيح فقط (Tab، وShift+Tab، وEnter، وSpace، ومفاتيح الأسهم). لاحظ العناصر التفاعلية التي يمكن الوصول إليها والوظيفية. ثم، دون إعادة تحميل الصفحة، انتقل إلى التنقل باللمس — انقر على الروابط والأزرار وعناصر التحكم في النماذج. تحقق من أن جميع الوظائف المتاحة عبر لوحة المفاتيح تظل متاحة عبر اللمس والعكس صحيح. وثّق أي عنصر يصبح غير قابل للوصول أو غير وظيفي بعد التبديل.
  6. \n
  7. اختبار إدخال مركّب مع قارئ الشاشة: باستخدام NVDA مع Firefox، تنقّل في الصفحة بلوحة المفاتيح لتفعيل وضع قارئ الشاشة. ثم استخدم شاشة اللمس (إن توفرت) لمحاولة التفاعل مع العناصر نفسها. تأكد من أن قارئ الشاشة والصفحة يستجيبان بشكل صحيح لكلا الإدخالين. كرر ذلك مع VoiceOver على Safari على iPad، باستخدام كل من إيماءات اللمس ولوحة مفاتيح Bluetooth مقترنة. مع JAWS على Chrome، تحقق من أن التبديل بين لوحة المفاتيح والفأرة لا يفسد إدارة التركيز أو يجعل العناصر التفاعلية غير قابلة للتشغيل.
  8. \n
  9. مراجعة الشيفرة بحثاً عن أنماط قفل الأنماط (modality-locking): راجع يدوياً أي مكتبات أو أطر عمل JavaScript مستخدمة في الصفحة بحثاً عن اكتشاف مدمج للأنماط. تتضمن بعض مكتبات واجهة المستخدم، خصوصاً الأطر القديمة الموجهة للجوال أولاً، شيفرة تعطل أحداث الفأرة أو لوحة المفاتيح على الأجهزة التي يُكتشف فيها اللمس. تحقق من توثيق المكتبة ومصدرها بحثاً عن مثل هذا السلوك وتأكد من أنه تم تجاوزه أو تعطيله.
  10. \n
  11. إعادة الاختبار بعد التفاعلات الديناميكية: نفّذ إجراءات تؤدي إلى تغييرات كبيرة في DOM — فتح نوافذ منبثقة (modals)، التنقل بين مسارات تطبيق صفحة واحدة (SPA)، إرسال نماذج — وأعد تشغيل اختبار الأنماط المتعددة بعد كل انتقال. أحياناً تُقدَّم القيود فقط في حالات تطبيقية محددة.
  12. \n
\n\n

كيفية الإصلاح

\n

اكتشاف اللمس لتعطيل التنقل بلوحة المفاتيح — غير صحيح

\n
<!-- JavaScript detects touch and removes all tabindex values,\n     breaking keyboard navigation for users who switch input modes -->\n<script>\n  window.addEventListener('touchstart', function() {\n    document.querySelectorAll('a, button, input, [tabindex]').forEach(function(el) {\n      el.setAttribute('tabindex', '-1');\n    });\n  }, { once: true });\n</script>
\n

اكتشاف اللمس لتعطيل التنقل بلوحة المفاتيح — صحيح

\n
<!-- Do not restrict keyboard accessibility based on touch detection.\n     Allow both input modalities to function concurrently.\n     If you need to manage focus styles for aesthetics, use the\n     :focus-visible CSS pseudo-class instead of removing tabindex. -->\n<style>\n  /* Show focus rings only for keyboard navigation, not mouse clicks,\n     without removing keyboard access entirely */\n  :focus:not(:focus-visible) {\n    outline: none;\n  }\n  :focus-visible {\n    outline: 3px solid #005fcc;\n    outline-offset: 2px;\n  }\n</style>\n<!-- No JavaScript modality detection needed -->
\n\n

استخدام حدث المؤشر لقمع أحداث لوحة المفاتيح — غير صحيح

\n
<!-- A custom slider that, upon receiving pointer input, stops\n     responding to keyboard arrow keys, locking the user into\n     pointer-only interaction -->\n<div id='slider' role='slider' aria-valuenow='50' aria-valuemin='0'\n     aria-valuemax='100' tabindex='0'></div>\n<script>\n  var slider = document.getElementById('slider');\n  var pointerUsed = false;\n  slider.addEventListener('pointerdown', function() {\n    pointerUsed = true;\n  });\n  slider.addEventListener('keydown', function(e) {\n    if (pointerUsed) return; // keyboard disabled after pointer interaction\n    if (e.key === 'ArrowRight') { /* increment */ }\n    if (e.key === 'ArrowLeft') { /* decrement */ }\n  });\n</script>
\n

استخدام حدث المؤشر لقمع أحداث لوحة المفاتيح — صحيح

\n
<!-- Both pointer and keyboard interactions are handled independently.\n     No flag is set that prevents one modality from working after\n     the other has been used. -->\n<div id='slider' role='slider' aria-valuenow='50' aria-valuemin='0'\n     aria-valuemax='100' tabindex='0'></div>\n<script>\n  var slider = document.getElementById('slider');\n  var value = 50;\n\n  function updateSlider(newValue) {\n    value = Math.max(0, Math.min(100, newValue));\n    slider.setAttribute('aria-valuenow', value);\n  }\n\n  // Pointer handler — always active\n  slider.addEventListener('pointermove', function(e) {\n    if (e.buttons === 1) {\n      // calculate new value from pointer position\n    }\n  });\n\n  // Keyboard handler — always active, not disabled by pointer use\n  slider.addEventListener('keydown', function(e) {\n    if (e.key === 'ArrowRight') updateSlider(value + 1);\n    if (e.key === 'ArrowLeft') updateSlider(value - 1);\n  });\n</script>
\n\n

إطار عمل للجوال يعطّل أحداث الفأرة تلقائياً — غير صحيح

\n\n

(Content truncated due to token limit — please retry this article.)