إنشاء مكوِّن أشرطة التنقّل

نظرة عامة أساسية حول كيفية إنشاء مكوّن شريط تنقّل سريع الاستجابة ويمكن الوصول إليه ليتمكّن المستخدمون من التنقّل في موقعك الإلكتروني

في هذه المشاركة، أود أن أشارككم أفكارًا حول طريقة لإنشاء مكونات شريط التنقل. جرِّب العرض التوضيحي

عرض توضيحي

إليك نسخة من هذه المشاركة على YouTube إذا كنت تفضّل ذلك:

نظرة عامة

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

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

تجربة المستخدم في الخلفية

في الفيديو التوضيحي للمكون أعلاه، فئات العناصر النائبة هي أنواع ألعاب الفيديو. يتم إنشاء هذا الممر من خلال التنقل في المسار التالي: home » rpg » indie » on sale، كما هو موضح أدناه.

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

هندسة المعلومات

أجد أنه من المفيد التفكير في المجموعات والعناصر.

المجموعات

المجموعة عبارة عن مجموعة من الخيارات للاختيار من بينها. من الصفحة الرئيسية نموذج شريط التنقّل في هذا المنشور، المجموعات هي ألعاب تقمّص الأدوار (FPS) ولعبة تقمّص الأدوار (RPG) والمعارك لعبة الزحف في الزنزانات والرياضة والألغاز.

السلع

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

في مصطلحات علوم الكمبيوتر، يمثل مكون شريط التنقل هذا متعددة الأبعاد المصفوفة:

const rawBreadcrumbData = {
  "FPS": {...},
  "RPG": {
    "AAA": {...},
    "indie": {
      "new": {...},
      "on sale": {...},
      "under 5": {...},
    },
    "self published": {...},
  },
  "brawler": {...},
  "dungeon crawler": {...},
  "sports": {...},
  "puzzle": {...},
}

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

التنسيقات

Markup

تبدأ المكونات الجيدة بـ HTML المناسب. في هذا القسم التالي، سأتناول خيارات الترميز وكيفية تأثيرها في المكوِّن العام.

مخطط داكن وفاتح

<meta name="color-scheme" content="dark light">

العلامة الوصفية color-scheme أعلاه يخبر المقتطف المتصفح بأن هذه الصفحة تتطلب المتصفح الفاتح والداكن. الأنماط. لا يتضمن أمثلة شريط التنقل أي CSS لمخططات الألوان هذه، وبالتالي ستستخدم أشرطة التنقّل الألوان التلقائية المتوفّرة في المتصفّح.

<nav class="breadcrumbs" role="navigation"></nav>

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

الرموز

وعند تكرار رمز على إحدى الصفحات، سيتم عرض رمز الرسومات الموجّهة التي يمكن تغيير حجمها (SVG) العنصر <use> يمكنك تحديد path مرة واحدة، واستخدامها لجميع مثيلات . ويمنع هذا تكرار معلومات المسار نفسها، ما يؤدي إلى مستندات أكبر واحتمال عدم اتساق المسار.

لاستخدام هذه التقنية، عليك إضافة عنصر SVG مخفي إلى الصفحة والتفاف الرموز في عنصر <symbol> بمعرّف فريد:

<svg style="display: none;">

  <symbol id="icon-home">
    <title>A home icon</title>
    <path d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
  </symbol>

  <symbol id="icon-dropdown-arrow">
    <title>A down arrow</title>
    <path d="M19 9l-7 7-7-7"/>
  </symbol>

</svg>

يقرأ المتصفح HTML بتنسيق SVG ويضع معلومات الرمز في الذاكرة مع استمرار بقية الصفحة التي تشير إلى المعرف لاستخدامات إضافية الأيقونة، كما يلي:

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-home" />
</svg>

<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
  <use href="#icon-dropdown-arrow" />
</svg>

أدوات مطوّري البرامج تعرض عنصر استخدام رسومات موجّهة يمكن تغيير حجمها (SVG)

يمكنك التحديد مرة واحدة واستخدام أي عدد تريده من المرات، مع الحد الأدنى من التأثير في أداء الصفحة والتصميم المرن. تمت إضافة aria-hidden="true" إلى عنصر SVG. لا فائدة من الرموز للمستخدم الذي يتصفح ولا يسمع سوى المحتوى، من هؤلاء المستخدمين يمنعهم من إضافة تشويش غير ضروري.

هذا هو المكان الذي يتباين فيه مسار التنقل التقليدي وتلك الموجودة في هذا المكون. في العادة، لا يكون هذا العنصر سوى رابط <a>، ولكنني أضفتُ تجربة مستخدم للاجتياز باستخدام التحديد المتخفي. تكون الفئة .crumb مسؤولة عن عرض الرابط الرمز، بينما يكون .crumbicon مسؤولاً عن تكديس الرمز واختيار العنصر معًا. وقد أطلقنا عليه اسم "الرابط المنقسم" لأن دواله شديدة يشبه زر التقسيم، ولكن بالنسبة للتنقل في الصفحات.

<span class="crumb">
  <a href="#sub-collection-b">Category B</a>
  <span class="crumbicon">
    <svg>...</svg>
    <select class="disguised-select" title="Navigate to another category">
      <option>Category A</option>
      <option selected>Category B</option>
      <option>Category C</option>
    </select>
  </span>
</span>

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

لقطة شاشة يظهر فيها عنصر التحديد غير المرئي الذي يتم تمريره فوقه
يتم عرض تلميح سياقي.

زخارف فاصلة

<span class="crumb-separator" aria-hidden="true">→</span>

إنّ الفواصل اختيارية، لكنّ إضافة عنصر واحد فقط سيفيدك أيضًا (شاهِد المثال الثالث في الفيديو. أعلاه). أُعطي بعد ذلك كل aria-hidden="true" منها لأنها زخرفية وليست وهو شيء يحتاج قارئ الشاشة إلى الإعلان عنه.

وتسهّل السمة gap، التي سنتناولها بعد ذلك، المسافات بين هذه المسافات.

الأنماط

بما أنّ اللون يستخدم ألوان النظام، فهو في الغالب فجوات وحزم للأنماط!

اتجاه التخطيط وتدفقه

&quot;أدوات مطوري البرامج&quot; تعرض محاذاة شريط التنقّل مع المحتوى المركّب على شكل المربع المرن
الجديدة.

يضبط عنصر التنقّل الأساسي nav.breadcrumbs موقع مخصّص على مستوى النطاق. التي يستخدمها الأطفال، بالإضافة إلى إنشاء محاذاة رأسية التصميم. يضمن هذا محاذاة الفتات والفواصل والأيقونات.

.breadcrumbs {
  --nav-gap: 2ch;

  display: flex;
  align-items: center;
  gap: var(--nav-gap);
  padding: calc(var(--nav-gap) / 2);
}

يتم عرض شريط تنقّل واحد بمحاذاة رأسية مع تراكبات flexbox.

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

.crumb {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--nav-gap) / 4);

  & > a {
    white-space: nowrap;

    &[aria-current="page"] {
      font-weight: bold;
    }
  }
}

تمت إضافة aria-current="page" للمساعدة في إبراز رابط الصفحة الحالية عن أَرْتَاح لن يكون لدى مستخدمي قارئ الشاشة مؤشر واضح على أن الرابط للصفحة الحالية، قمنا بتصميم العنصر بشكل مرئي لمساعدة المستخدمين المبصرين في الحصول على تجربة مستخدم مماثلة.

يستخدم المكوِّن .crumbicon شبكة لتكديس رمز SVG مع رمز غير مرئي" العنصر <select>

تم عرض &quot;أدوات مطوّري البرامج في الشبكة&quot; متراكبة على زر حيث يكون الصف والعمود معًا
باسم المكدس.

.crumbicon {
  --crumbicon-size: 3ch;

  display: grid;
  grid: [stack] var(--crumbicon-size) / [stack] var(--crumbicon-size);
  place-items: center;

  & > * {
    grid-area: stack;
  }
}

العنصر <select> هو الأخير في DOM، لذلك يكون في أعلى المكدس، وتفاعلية. أضِف نمط opacity: .01 حتى يظل العنصر قابلاً للاستخدام، والنتيجة هي مربع تحديد يتناسب تمامًا مع شكل الأيقونة. هذه طريقة رائعة لتخصيص مظهر عنصر <select> الحفاظ على الوظيفة المضمنة.

.disguised-select {
  inline-size: 100%;
  block-size: 100%;
  opacity: .01;
  font-size: min(100%, 16px); /* Defaults to 16px; fixes iOS zoom */
}

القائمة الكاملة

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

.breadcrumbs {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: calc(var(--nav-gap) / 2);

  & > .crumb:last-of-type {
    scroll-snap-align: end;
  }

  @supports (-webkit-hyphens:none) { & {
    scroll-snap-type: none;
  }}
}

تقوم الأنماط الكاملة بإعداد تجربة المستخدم التالية:

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

الاستعلامات عن الوسائط

أحد التعديلات الطفيفة لإطارات العرض الأصغر هو إخفاء "الصفحة الرئيسية" تسمية، مغادرة الرمز فقط:

@media (width <= 480px) {
  .breadcrumbs .home-label {
    display: none;
  }
}

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

تسهيل الاستخدام

الحركة

ليس هناك الكثير من الحركة في هذا المكون، ولكن من خلال إحاطة انتقال في عملية فحص prefers-reduced-motion، يمكننا منع الحركة غير المرغوب فيها.

@media (prefers-reduced-motion: no-preference) {
  .crumbicon {
    transition: box-shadow .2s ease;
  }
}

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

JavaScript

أولهما، وبغض النظر عن نوع جهاز التوجيه الذي تستخدمه في موقعك أو تطبيقك، عندما يغيّر المستخدم أشرطة التنقّل، يجب تعديل عنوان URL والمستخدم. عرض الصفحة المناسبة. ثانيًا، من أجل تسوية تجربة المستخدم، تأكد من لا تحدث عمليات تنقل غير متوقعة عند تصفّح المستخدمين <select> فقط. الخيارات.

هناك إجراءان مهمان لتجربة المستخدم يجب التعامل معه بواسطة JavaScript: الخيار "تحديد" تغيير حريص <select> لمنع تنشيط حدث التغيير.

يجب منع الحدث شديدًا بسبب استخدام <select> العنصر. على Windows Edge وربما في المتصفحات الأخرى أيضًا، انقر على زر changed يتم تنشيط الحدث عندما يتصفّح المستخدم الخيارات باستخدام لوحة المفاتيح. هذا هو السبب في أنني وصفه بأنّه حريص، لأنّ المستخدم لم يحدّد سوى بشكل زائف الخيار، مثل التمرير أو التركيز، ولكنها لم تؤكّد الاختيار باستخدام enter أو click. الحماس يؤدي الحدث إلى عدم إمكانية الوصول إلى ميزة تغيير فئة المكون هذه، لأن وسيؤدي فتح مربع التحديد وتصفح أحد العناصر ببساطة إلى تنشيط الحدث تغيير الصفحة، قبل أن يصبح المستخدم جاهزًا.

حدث تغيير أفضل من "<select>"

const crumbs = document.querySelectorAll('.breadcrumbs select')
const allowedKeys = new Set(['Tab', 'Enter', ' '])
const preventedKeys = new Set(['ArrowUp', 'ArrowDown'])

// watch crumbs for changes,
// ensures it's a full value change, not a user exploring options via keyboard
crumbs.forEach(nav => {
  let ignoreChange = false

  nav.addEventListener('change', e => {
    if (ignoreChange) return
    // it's actually changed!
  })

  nav.addEventListener('keydown', ({ key }) => {
    if (preventedKeys.has(key))
      ignoreChange = true
    else if (allowedKeys.has(key))
      ignoreChange = false
  })
})

واستراتيجية ذلك هي مراقبة أحداث لوحة المفاتيح المتّجهة للأسفل في كل <select>. ويحدد ما إذا كان المفتاح الذي تم الضغط عليه هو تأكيد التنقل (Tab أو Enter) أو التنقل المكاني (ArrowUp أو ArrowDown). مع هذا القرار، يمكن للمكون أن يقرر الانتظار أو الانتقال، عندما يكون الحدث يتم تنشيط عنصر <select>.

الخاتمة

الآن بعد أن تعرّفت على كيفية إجراء ذلك، كيف يمكنك‽ 🙂

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

ريمكسات من إنشاء المنتدى