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

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

Manuel Matuzović
Manuel Matuzović

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

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

بناء طبقة تلو الأخرى

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

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

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

  • HTML

    <a href="/home">Home</a>
    <a href="/about-us">About us</a>
    <a href="/pricing">Pricing</a>
    <a href="/contact">Contact</a>
    
  • CSS

    /* 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>

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

تشير السمة aria-current (الحالة) إلى العنصر الذي يمثّل العنصر الحالي ضمن حاوية أو مجموعة من العناصر ذات الصلة. رمز مميّز للصفحة يُستخدَم للإشارة إلى رابط ضمن مجموعة من روابط تقسيم الصفحات، حيث يتم تصميم الرابط بشكل مرئي لتمثيل الصفحة المعروضة حاليًا. [Accessible Rich Internet Applications (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. في VoiceOver، يمكنك استخدام الدوّار لإدراج جميع المعالم على الصفحة بالضغط على VO ‏+ U.

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

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

إذا كان لديك شريط تنقّل على مستوى الموقع الإلكتروني وشريط تنقّل محلي للصفحة وتقسيم صفحات على صفحة واحدة، قد يكون لديك أيضًا 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، لإنشاء تأثير التمرير أو التلاشي. لن ينجح ذلك مع السمة display: none لأنّ السمة display لا يمكن تحريكها.

تستخدم انتقالات 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 في الاستعلام عن الوسائط prefers-reduced-motion لأنّ الصور المتحركة يمكن أن تؤدي إلى الغثيان والدوخة والصداع لدى بعض المستخدمين.

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 بكسل حول رابط مركَّز في الإصدار 103 من Chrome

ويمكنك تحسين ذلك من خلال تقديم أنماطك الخاصة بألوانك الخاصة. باستخدام :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

Browser Support

  • Chrome: 86.
  • Edge: 86.
  • Firefox: 85.
  • Safari: 15.4.

Source

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

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

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

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

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

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

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

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

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

دور التنقّل

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

navigation (role) WAI-ARIA 1.1

دور القائمة

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

menu (role) WAI-ARIA 1.1

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

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

menubar (role) WAI-ARIA 1.1

دور menuitem

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

menuitem (role) 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.

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

مراجع إضافية