إنشاء شريط التنقل الرئيسي لموقع ويب

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

مانويل ماتوزوفيتش
مانويل ماتوزوفيتش

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

بالنسبة إلى معظم المواقع الإلكترونية، تريد إنشاء شيء ليس بسيطًا جدًا ولا معقدًا جدًا.

البناء حسب الطبقة

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

البنية الأساسية

لإجراء التنقّل الأساسي، تحتاج إلى أمرَين: عناصر <a> وبضعة أسطر من CSS لتحسين النمط والتنسيق التلقائي لروابطك.

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Define variables for your colors */
:root {
  --color-shades-dark: rgb(25, 25, 25);
}

/* Use the alternative box model
Details: <https://web.dev/learn/css/box-model/> */
*{
  box-sizing: border-box;
}

/* Basic font styling */
body {
  font-family: Segoe UI, system-ui, -apple-system, sans-serif;
  font-size: 1.6rem;
}

/* Link styling */
a {
  --text-color: var(--color-shades-dark);
  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  display: inline-block;
  margin-block-end: 0.5rem; /* See note at the bottom of this chapter */
  margin-inline-end: 0.5rem;
  padding: 0.1rem;
  text-decoration: none;
}

/* Change the border-color on :hover and :focus */
a:where(:hover, :focus) {
  --border-color: var(--text-color);
}
اطّلِع على الخطوة 1: HTML وCSS الأساسي" على CodePen.

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

إليك ما يمكنك فعله:

  • حدِّد الصفحة النشطة.
  • الإعلان عن عدد العناصر لمستخدمي برامج قراءة الشاشة
  • أضِف مَعلمًا واسمح لمستخدمي برامج قراءة الشاشة بالوصول إلى قائمة التنقّل مباشرةً باستخدام اختصار.
  • إخفاء التنقل في إطارات العرض الضيقة.
  • تحسين نمط التركيز

تمييز الصفحة النشطة

لتمييز الصفحة النشطة، يمكنك إضافة فئة إلى الرابط المقابل.

<a href="/about-us" class="active-page">About us</a>

وتكمن المشكلة في هذا المنهج في أنه ينقل المعلومات النشطة بصريًا فقط. لم يتمكن مستخدم قارئ الشاشة المكشوف من التفريق بين الصفحة النشطة والصفحات الأخرى. لحسن الحظ، يوفّر معيار تطبيقات الإنترنت الغنية بصريًا القابلة للوصول (ARIA) وسيلة لإيصال هذه المعلومات أيضًا من الناحية الدلالية. استخدِم السمة والقيمة aria-current="page" بدلاً من فئة.

تشير السمة aria-current (الحالة) إلى العنصر الذي يمثّل العنصر الحالي داخل حاوية أو مجموعة من العناصر ذات الصلة. رمز مميز للصفحة يُستخدم للإشارة إلى رابط داخل مجموعة من روابط التقسيم على صفحات، حيث يتم تصميم الرابط بشكل مرئي لتمثيل الصفحة المعروضة حاليًا. [تطبيقات الإنترنت التفاعلية المتاحة للوصول (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)

باستخدام السمة الإضافية، يعلن قارئ الشاشة الآن عن عبارة مثل "الصفحة الحالية، الرابط، نبذة عنّا" بدلاً من مجرد "رابط، نبذة عنّا".

<a href="/about-us" aria-current="page" class="active-page">About us</a>

ومن الآثار الجانبية الملائمة لذلك أنّه يمكنك استخدام السمة لاختيار الرابط النشط في CSS، ما يجعل فئة active-page قديمة.

<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
  --border-color: var(--color-highlight);
  --text-color: var(--color-highlight);
}
اطّلِع على الخطوة 2: تمييز الصفحة النشطة على CodePen.

الإعلان عن عدد العناصر

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

<ul>
  <li>
     <a href="/home">Home</a>
  </li>
  <li>
    <a href="/about-us" aria-current="page">About us</a>
  </li>
  <li>
    <a href="/pricing">Pricing</a>
  </li>
  <li>
    <a href="/contact">Contact</a>
  </li>
</ul>

عندما يعثر مستخدم قارئ الشاشة على القائمة، سيعلن برنامجه عن شيء مثل "قائمة، 4 عناصر".

في ما يلي عرض توضيحي للتنقّل المستخدَم مع قارئ الشاشة NVDA في نظام التشغيل Windows.

عليك الآن تعديل التصميم لجعله يبدو كما كان من قبل.

/* Remove the default list styling and create a flexible layout for the list */
ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Basic link styling */
a {
  --text-color: var(--color-shades-dark);

  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  padding: 0.1rem;
  text-decoration: none;
}

يمكن أن يكون لاستخدام القوائم عدة مزايا لمستخدمي برامج قراءة الشاشة:

  • ويمكنهم الحصول على العدد الإجمالي للعناصر قبل تفاعلهم مع العناصر.
  • قد يستخدمون اختصارات للانتقال من عنصر قائمة إلى عنصر في القائمة.
  • قد يستخدمون اختصارات للانتقال من قائمة إلى أخرى.
  • قد يعلن قارئ الشاشة عن فهرس العنصر الحالي (على سبيل المثال، "عنصر القائمة، اثنان من أربعة").

بالإضافة إلى ذلك، إذا تم عرض الصفحة بدون CSS، ستعرض القائمة الروابط كمجموعة متماسكة من العناصر بدلاً من كومة من الروابط.

من التفاصيل البارزة عن VoiceOver في Safari، أنّك ستفقد جميع هذه المزايا عند ضبط list-style: none. يتم ذلك حسب التصميم. قرّر فريق WebKit إزالة دلالات القائمة، عندما لا تبدو القائمة كقائمة. واستنادًا إلى مدى تعقيد عملية التنقّل، قد تكون هذه مشكلة أو لا. من ناحية، لا يزال التنقل قابلاً للاستخدام ويؤثر فقط في VoiceOver في Safari. سيظل بإمكان VoiceOver في Chrome أو Firefox الإعلان عن عدد العناصر بالإضافة إلى برامج قراءة الشاشة الأخرى، مثل NVDA. من ناحية أخرى، قد تكون المعلومات الدلالية مفيدة حقًا في بعض المواقف. ولاتخاذ هذا القرار، يجب عليك اختبار التنقل مع مستخدمي قارئ الشاشة الفعليين والحصول على ملاحظاتهم. إذا قررت أنّك بحاجة إلى VoiceOver في Safari لتعمل مثل جميع برامج قراءة الشاشة الأخرى، يمكنك التغلب على هذه المشكلة من خلال ضبط دور قائمة ARIA بشكلٍ صريح على <ul>. ويؤدي هذا إلى إعادة السلوك إلى حالته قبل إزالة نمط القائمة. من الناحية المرئية، لا تزال القائمة كما هي.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
اطّلِع على الخطوة 3: الإعلان عن عدد العناصر في CodePen.

إضافة مَعلم

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

وهناك العديد من المزايا لاستخدام العنصر <nav>. وعلى وجه التحديد، يُعلن قارئ الشاشة عن شيء مثل "التنقل"، عندما يتفاعل المستخدم معه، ويضيف مَعلمًا إلى الصفحة. المعالم هي مناطق خاصة على الصفحة، مثل <header> أو <footer> أو <main>، يمكن لقارئ الشاشة الانتقال إليها. يمكن أن يكون وجود معالم على الصفحة مفيدًا، لأنه يسمح لمستخدمي برامج قراءة الشاشة بالوصول إلى المناطق المهمة على الصفحة مباشرة دون الحاجة إلى التفاعل مع باقي الصفحة. على سبيل المثال، يمكنك الانتقال من مَعلم إلى آخر بالضغط على المفتاح D في NVDA. في ميزة "التعليق الصوتي"، يمكنك استخدام الدوار لإدراج جميع المَعالم على الصفحة من خلال الضغط على VO + U.

قائمة بأربعة معالم، هي: بانر، وتنقُّل، ومعلومات رئيسية، ومعلومات المحتوى.
يسرد دوّار في VoiceOver جميع المعالم في صفحة.

في هذه القائمة، يظهر لك 4 معالم: بانر، وهو العنصر <header>، والتنقّل هو <nav>، والعنصر الرئيسي، ومعلومات المحتوى هي <footer>.<main> يجب ألا تكون هذه القائمة طويلة جدًا، فأنت تريد فقط وضع علامة على الأجزاء المهمة من واجهة المستخدم باعتبارها معالم، مثل البحث في الموقع الإلكتروني أو التنقل المحلي أو التقسيم على صفحات.

إذا كانت لديك عملية تنقّل على مستوى الموقع الإلكتروني، وتنقل محلي للصفحة، وتقسيم على صفحات على صفحة واحدة، يمكن أن يكون لديك أيضًا 3 عناصر <nav>. لا بأس بذلك، ولكن هناك الآن ثلاثة معالم للتنقل، ودلاليًا، تبدو جميعها متشابهة. من الصعب التمييز بينهما، ما لم تكن تعرف بنية الصفحة جيدًا.

صورة تعرض ثلاثة معالم تشير جميعها إلى &quot;التنقل&quot;.
يسرد دوّار في VoiceOver ثلاثة معالم تنقُّل غير مصنّفة.

للتمييز بينهما، يجب تصنيفهما باستخدام aria-labelledby أو aria-label.

<nav aria-label="Main">
    <ul>
      <li>
         <a href="/home">Home</a>
      </li>
      ...
  </ul>
</nav>
...
<nav aria-label="Select page">
    <ul>
      <li>
         <a href="/page-1">1</a>
      </li>
      ...
    </ul>
</nav>

إذا كان التصنيف الذي اخترته متوفّرًا في مكان ما في الصفحة، يمكنك استخدام السمة aria-labelledby بدلاً من ذلك والإشارة إلى التصنيف الحالي باستخدام السمة id.

<nav aria-labelledby="pagination_heading">
  <h2 id="pagination_heading">Select a page</h2>
  <ul>
    <li>
       <a href="/page-1">1</a>
    </li>
    ...
  </ul>
</nav>

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

المَعالم
VoiceOver يدرج المعالم "بانر" و"شريط التنقل الرئيسي" و"الرئيسي" و"التنقل في الصفحة" و"اختيار التنقل في الصفحة" و "معلومات المحتوى".
اطّلِع على الخطوة 4: إضافة مَعلم في CodePen.

إخفاء التنقل في إطارات العرض الضيقة

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

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

إضافة زر برغر

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

صفحة تعرض زر برغر.
النتيجة: بدلاً من إضافة الروابط، يعرض شريط التنقّل زر برغر على إطارات عرض ضيقة.
<nav id="mainnav">
  ...
</nav>

<template id="burger-template">
  <button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
    <svg width="24" height="24" aria-hidden="true">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
    </svg>
  </button>
</template>
  1. تحدّد السمة aria-expanded لبرنامج قارئ الشاشة ما إذا كان قد تم توسيع عنصر التحكّم في الزر.
  2. تعطي الإضافة "aria-label" للزر اسمًا يُسمّى "سهل الوصول"، وهو بديل نصي لرمز البرغر.
  3. يمكنك إخفاء "<svg>" من التكنولوجيا المساعِدة باستخدام "aria-hidden" لأنّه يتضمن تصنيفًا نصيًا مقدّمًا من "aria-label".
  4. يخبر aria-controls بالتكنولوجيا المساعِدة التي توفِّر السمة (مثل JAWS)، وهو العنصر الذي يتحكم فيه الزر.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');

// Toggle aria-expanded attribute
button.addEventListener('click', e => {
  // aria-expanded="true" signals that the menu is currently open
  const isOpen = button.getAttribute('aria-expanded') === "true"
  button.setAttribute('aria-expanded', !isOpen);
});

// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    button.setAttribute('aria-expanded', false);
  }
});

// Add the button to the page
nav.insertBefore(burgerClone, list);
  1. من السهل أن تتوفر للمستخدمين إمكانية إغلاق شريط التنقل وقتما يريدون، مثلاً عن طريق الضغط على مفتاح Escape.
  2. من المهم استخدام insertBefore بدلاً من appendChild لأنّ الزر يجب أن يكون العنصر الأول في التنقّل. إذا ضغط مستخدم لوحة مفاتيح أو قارئ شاشة على مفتاح التبويب (Tab) بعد النقر على الزر، يتوقّع التركيز على العنصر الأول في القائمة. إذا كان الزر يأتي بعد القائمة، فلن يكون هذا هو الحال.

بعد ذلك، يمكنك إعادة تعيين النمط الافتراضي للزر والتأكد من ظهوره فقط في إطارات العرض الضيقة.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
اطّلِع على الخطوة 5: إضافة زر برغر على CodePen.

إخفاء القائمة

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

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
}

nav {
  position: var(--nav-position, fixed);
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
}

بعد ذلك، يمكنك تغيير التنسيق على إطارات العرض الضيقة من خلال إضافة خاصية مخصّصة جديدة (—-nav-list-layout). يكون التخطيط عموديًا بشكل افتراضي وينتقل إلى الصفوف على الشاشات الأكبر حجمًا.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }

  ul {
    --nav-list-layout: row;
  }
}

ul {
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

يجب أن يظهر شريط التنقل على النحو التالي في إطارات العرض الضيقة.

الصفحة التي تعرض قائمة التنقل وزر البرغر.
يتم وضع كل من زر البرجر والقائمة في الزاوية العلوية من إطار العرض.

تحتاج القائمة بوضوح إلى بعض CSS. سننقله إلى أعلى يمين الشاشة، ونجعله يملأ الشاشة بأكملها عموديًا، ونطبِّق background-color وbox-shadow.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
  
  ul {
    --nav-list-layout: row;
    --nav-list-position: static;
    --nav-list-padding: 0;
    --nav-list-height: auto;
    --nav-list-width: 100%;
    --nav-list-shadow: none;
  }
}

ul {
  background: rgb(255, 255, 255);
  box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  height: var(--nav-list-height, 100vh);
  list-style: none;
  margin: 0;
  padding: var(--nav-list-padding, 2rem);
  position: var(--nav-list-position, fixed);
  inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
  inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
  width: var(--nav-list-width, min(22rem, 100vw));
}

button {
  all: unset;
  display: var(--nav-button-display, flex);
  position: relative;
  z-index: 1;
}

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

قائمة التنقّل مفتوحة.

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

في وقت سابق، أضفت حدث نقرة إلى الزر لتبديل قيمة سمة aria-expanded. يمكنك استخدام هذه المعلومات كشرط لعرض القائمة وإخفائها في CSS.

@media (min-width: 48em) {
  ul {
    --nav-list-visibility: visible;
  }
}

ul {
  visibility: var(--nav-list-visibility, visible);
}

/* Hide the list on narrow viewports, if it comes after an element with
   aria-expanded set to "false". */
[aria-expanded="false"] + ul {
  visibility: var(--nav-list-visibility, hidden);
}

من المهم استخدام بيان خاصية مثل visibility: hidden أو display: none بدلاً من opacity: 0 أو translateX(100%) لإخفاء القائمة. وتضمن هذه السمات أنّه لا يمكن التركيز على الروابط عندما يكون التنقّل مخفيًا. سيؤدي استخدام الترميز opacity أو translate إلى إزالة المحتوى بشكل مرئي لتصبح الروابط غير مرئية ولكن لا يزال من الممكن الوصول إليها باستخدام لوحة المفاتيح، وهو ما سيكون مربكًا ومحبطًا. يؤدي استخدام الترميز visibility أو display إلى إخفاء البيانات بصريًا وعدم إمكانية الوصول إليها، وبالتالي إخفائها لجميع المستخدمين.

اطّلِع على الخطوة 6: إخفاء القائمة.

تحريك القائمة

إذا كنت تتساءل عن سبب استخدام visibility: hidden; بدلاً من display: none;، لأنّه يمكنك إضافة تأثيرات حركية إلى مستوى الظهور. وتتضمّن حالتَين حالتَين فقط، هما hidden وvisible، ولكن يمكنك دمجها مع سمة أخرى، مثل transform أو opacity، لإنشاء تأثير انتقال أو تلاشي للداخل. لا يعمل ذلك مع ميزة العرض: لا شيء لأن خاصية العرض غير متحركة.

تعمل إعدادات CSS التالية على نقل opacity لإنشاء تأثير التلاشي للداخل والاختفاء التدريجي.

ul {
  transition: opacity 0.6s linear, visibility 0.3s linear;
  visibility: var(--nav-list-visibility, visible);
}

[aria-expanded="false"] + ul {
  opacity: 0;
  visibility: var(--nav-list-visibility, hidden);
}

إذا كنت تريد إضافة تأثيرات حركية إلى محتوى حركي بدلاً من ذلك، ننصحك بإدراج السمة transition في استعلام وسائط يفضل-sرفض-الحركة لأنّ الرسوم المتحركة يمكن أن تؤدي إلى الغثيان والدوار والصداع لدى بعض المستخدمين.

ul {
  visibility: var(--nav-list-visibility, visible);
}

@media (prefers-reduced-motion: no-preference) {
  ul {
    transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
  }
}

[aria-expanded="false"] + ul {
  transform: var(--nav-list-transform, translateX(100%));
  visibility: var(--nav-list-visibility, hidden);
}

ويضمن ذلك أن الأشخاص الذين ليس لديهم تفضيل للحركة المنخفضة هم فقط من يمكنهم رؤية الرسوم المتحركة.

اطّلِع على الخطوة 7: تحريك القائمة على CodePen.

تحسين نمط التركيز

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

وفي ما يلي كيفية ظهور أنماط التركيز التلقائية على الرابط في الإصدار 103 من Chrome.

مخطط أزرق مقاس 2 بكسل حول رابط محلّ التركيز في Chrome 103

يمكنك تحسين ذلك من خلال توفير أنماطك الخاصة بألوانك الخاصة. وعند استخدام :focus-visible بدلاً من :focus، يمكنك السماح للمتصفّح بتحديد الوقت المناسب لعرض أنماط التركيز. ستكون أنماط :focus مرئية للجميع، سواء باستخدام الماوس ولوحة المفاتيح أو اللمس، بغض النظر عمّا إذا كانوا بحاجة إليها أم لا. يستخدم المتصفِّح :focus-visible إشارات إرشادية داخلية لتحديد ما إذا كان سيتم عرضها لمستخدمي لوحة المفاتيح فقط أو للجميع.

/* Remove the default :focus outline */
*:focus {
  outline: none;
}

/* Show a custom outline on :focus-visible */
*:focus-visible {
  outline: 2px solid var(--color-shades-dark);
  outline-offset: 4px;
}

المتصفِّح متوافق مع :focus-visible

التوافق مع المتصفح

  • 86
  • 86
  • 85
  • 15.4

المصدر

مخطط داكن اللون 2 بكسل مرئي بوضوح مع مسافات بداخله.

هناك طرق مختلفة لإبراز العناصر عندما يكون التركيز عليها. ويُنصَح باستخدام السمة outline لأنّها لا تعطّل التنسيق، وهو ما قد يحدث مع border. كما أنّها تعمل جيدًا مع وضع التباين العالي على نظام التشغيل Windows. المواقع التي لا تعمل بشكل جيد هي background-color أو box-shadow، لأنه قد لا يتم عرضها على الإطلاق باستخدام إعدادات تباين مخصصة.

موقع إلكتروني بخلفية داكنة يكون التركيز عليها مظللاً باللون الأرجواني.
اطّلِع على الخطوة 8: تحسين أنماط التركيز على CodePen.

تهانينا! لقد أنشأت شريط تنقّل رئيسيًا محسَّنًا تدريجيًا وغنيًا دلاليًا وسهل الوصول إليه ومتوافقًا مع الأجهزة الجوّالة.

هناك دائمًا شيء يمكن تحسينه، على سبيل المثال:

  • يمكنك حصر التركيز على شريط التنقّل أو جعل بقية الصفحة غير متصلة بإطارات عرض ضيقة.
  • يمكنك إضافة رابط تخطي أعلى الصفحة للسماح لمستخدمي لوحة المفاتيح بتخطّي التنقل.

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

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

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

دور التنقّل

مجموعة من عناصر التنقل (عادةً الروابط) للتنقل في المستند أو المستندات ذات الصلة.

التنقل (الدور) WAI-ARIA 1.1

دور القائمة

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

القائمة (الدور) WAI-ARIA 1.1

دور شريط القوائم

عرض تقديمي للقائمة التي تظل مرئية عادةً ويتم تقديمها عادةً أفقيًا. يتم استخدام دور شريط القوائم لإنشاء شريط قوائم مشابهًا لتلك الموجودة في تطبيقات سطح المكتب في Windows وMac وGnome. يتم استخدام شريط القوائم لإنشاء مجموعة متسقة من الأوامر المستخدمة بشكل متكرر. يجب أن يتأكّد المؤلفون من أنّ تفاعل شريط القوائم مشابه للتفاعل المعتاد لشريط القوائم في واجهة المستخدم الرسومية لسطح المكتب.

Menubar (role) WAI-ARIA 1.1

دور عنصر القائمة

خيار في مجموعة من الخيارات المضمّنة في قائمة أو شريط قائمة.

القائمة (الدور) WAI-ARIA 1.1

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

متى تكون القائمة مناسبة؟

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

<ul>
  <li>
    Product 1

    <button aria-expanded="false" aria-controls="options1">Edit</button>

    <div role="menu" id="options1">
      <button role="menuitem">
        Duplicate
      </button>
      <button role="menuitem">
        Delete
      </button>
      <button role="menuitem">
        Disable
      </button>
    </div>
  </li>
  <li>
    Product 2
    ...
  </li>
</ul>

تداعيات استخدام أدوار القائمة

من المهم حقًا استخدام أدوار القائمة هذه بحكمة لأن الكثير يمكن أن يحدث خطأ.

تتوقّع القوائم بنية DOM معيّنة. يجب أن يكون menuitem عنصرًا ثانويًا مباشرًا من menu. يمكن للكود التالي أن يكسر السلوك الدلالي:

 <!-- Wrong, don't do this -->
<ul role="menu">
  <li>
    <a href="#" role="menuitem">Item 1</a>
  </li>
</ul>

يتوقع المستخدمون المتمرسون أن تعمل بعض اختصارات لوحة المفاتيح مع القوائم وأشرطة القوائم. استنادًا إلى دليل ممارسات تأليف ARIA (APG)، يتضمّن ذلك ما يلي:

  • Enter ومفتاح المسافة لتحديد عناصر القائمة.
  • مفاتيح الأسهم في جميع الاتجاهات للتنقل بين العناصر.
  • مفتاحا Home وEnd لنقل التركيز إلى العنصر الأول أو الأخير على التوالي.
  • a-z لنقل التركيز إلى عنصر القائمة التالي بتصنيف يبدأ بالحرف المكتوب.
  • اضغط على Esc لإغلاق القائمة.

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

وينطبق ذلك على مستخدمي لوحة المفاتيح الذين قد يتوقّعون أن يتمكّنوا من استخدام Shift وShift + Tab.

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

مراجع إضافية

صورة رئيسية من تصميم ميك هاوبت