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

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

Manuel Matuzović
Manuel Matuzović

هناك العديد من الطرق المختلفة لإنشاء شريط التنقل الرئيسي في موقع الويب، من حيث التصميم والوظائف والترميز الأساسي والمعلومات الدلالية. إذا كان التنفيذ بسيطًا للغاية، سيكون مناسبًا لمعظم الأشخاص، ولكن قد لا تكون تجربة المستخدم (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=&quot;page&quot; بدلاً من الفئة.

تشير السمة 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> والرئيسي للعنصر <main> ومعلومات المحتوى هي <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>

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

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

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)، إلا أنّ استخدام أنماط تركيز مخصّصة مرئية بشكلٍ أوضح يحسِّن تجربة المستخدم.

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

مخطط أزرق بحجم 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 من متصفّح Chrome
  • الحافة: 86.
  • Firefox: 85.
  • Safari: الإصدار 15.4.

المصدر

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

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

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

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

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

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

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

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

دور التنقّل

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

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

دور القائمة

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

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

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

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

الإصدار 1.1 من شريط القائمة (الدور) WAI-ARIA

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

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

الإصدار 1.1 من عنصر القائمة (الدور) WAI-ARIA

المواصفات واضحة جدًا هنا، استخدم التنقل للتنقل في المستند أو المستندات ذات الصلة والقائمة فقط لقائمة من الإجراءات أو الوظائف المشابهة للقوائم في تطبيقات سطح المكتب. إذا لم تكن بصدد إنشاء المستند التالي في "مستندات 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، يشمل ذلك ما يلي:

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

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

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

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

موارد إضافية

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