إنشاء مكون تمرير الوسائط

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

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

العرض التوضيحي

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

نظرة عامة

سنقوم ببناء تخطيط تمرير أفقي مخصص لاستضافة الصور المصغرة للوسائط أو المنتجات. يبدأ المكوّن كقائمة <ul> متواضعة، ولكن يتم تحويلها باستخدام CSS إلى تجربة تمرير سلسة ومُرضية، من خلال عرض الصور وترتيبها في شبكة. تتم إضافة JavaScript لتسهيل تفاعلات فهرس التنقل، ما يساعد مستخدمي لوحة المفاتيح في تخطّي التنقّل في أكثر من 100 عنصر. بالإضافة إلى ذلك، يتم استخدام طلب بحث تجريبي للوسائط، وهو prefers-reduced-data، لتحويل أداة التمرير في الوسائط إلى تجربة خفيفة الوزن للتمرير في العناوين.

البدء بترميز سهل الاستخدام

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

أرسِل قائمة تتضمّن عنصر <ul>:

<ul class="horizontal-media-scroller">
  <li></li>
  <li></li>
  <li></li>
  ...
<ul>

يمكنك جعل عناصر القائمة تفاعلية باستخدام عنصر <a>:

<li>
  <a href="#">
    ...
  </a>
</li>

استخدِم عنصر <figure> لتمثيل صورة وترجمتها بشكل دلالي:

<figure>
  <picture>
    <img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
  </picture>
  <figcaption>Legends</figcaption>
</figure>

لاحِظ السمتَين alt وloading في <img>. النص البديل في شريط تمرير الوسائط هو فرصة لتجربة المستخدم للمساعدة في إضافة سياق إضافي للصورة المصغّرة، أو كنص احتياطي في حال عدم تحميل الصورة، أو يوفّر واجهة مستخدم منطوقة للمستخدمين الذين يعتمدون على التكنولوجيا المساعِدة، مثل قارئ الشاشة. اطّلِع على مزيد من المعلومات من خلال القواعد الذهبية الخمسة لإنشاء نص بديل ممتثل.

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

إتاحة خيارات الألوان المفضّلة للمستخدم

استخدِم color-scheme كعلامة <meta> للإشارة إلى المتصفّح بأنّ صفحتك تريد استخدام أنماط وكيل المستخدم الفاتحة والداكنة المقدَّمة. وهو وضع مُعتم مجاني أو وضع الإضاءة الساطعة، حسب طريقة النظر إليه:

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

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

يمكنك الاطّلاع على مزيد من المعلومات من توماس شتاينر على الرابط https://web.dev/color-scheme/.

إضافة محتوى

استنادًا إلى بنية المحتوى أعلاه لصفحة ul > li > a > figure > picture > img، تتمثل المهمة التالية في إضافة صور وعناوين للتنقّل بينها. لقد ضمّنت في العرض التجريبي صورًا ونصًا ثابتَين لعناصر نائبة، ولكن يمكنك استخدام مصدر البيانات المفضّل لديك.

إضافة نمط باستخدام CSS

حان الوقت الآن لخدمة CSS لاستخدام هذه القائمة العامة للمحتوى وتحويلها إلى تجربة. تستخدِم منصة Netflix ومتاجر التطبيقات وغيرها الكثير من المواقع الإلكترونية والتطبيقات مناطق التمرير الأفقي لتعبئة مساحة العرض بالفئات والخيارات.

إنشاء تنسيق شريط التمرير

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

2
يتم عرض صفوف قابلة للانتقال. لا يحتوي أحدهما على علامة شرطة ممتدة، ما يعني أنّه أطول ويكون كل عنوان
مقروءًا بالكامل. أما الصفحة الأخرى، فهي أقصر والعديد من العناوين مقطوعة باستخدام علامة ملفوظة.

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

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
  margin: 0;
}

يستخدم العنصر <picture> السمة المخصّصة بعد ذلك لإنشاء نسبة العرض إلى الارتفاع الأساسية، وهي مربّع:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

يمكنك إضافة بعض الأنماط البسيطة لإكمال العناصر الأساسية لشريط تمرير الوسائط:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  & > li {
    display: inline-block; /* removes the list-item bullet */
  }

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

يؤدي ضبط overflow إلى إعداد <ul> للسماح بالتمرير والتنقّل باستخدام لوحة المفاتيح في قائمته، ثم تتم إزالة ::marker من كل عنصر ثانوي مباشر من النوع <li> من خلال الحصول على نوع عرض جديد من النوع inline-block.

الصور لا تستجيب حتى الآن، وتنفصل مباشرة من الصناديق الموجودة بداخلها. يمكنك استخدام بعض الأنماط للحجم والملاءمة والحدود، وتحديد تدرّج في الخلفية عند استخدام ميزة "التحميل المُتأخّر":

img {
  /* smash into whatever box it's in */
  inline-size: 100%;
  block-size: 100%;

  /* don't squish but do cover the space */
  object-fit: cover;

  /* soften the edges */
  border-radius: 1ex;
  overflow: hidden;

  /* if empty, show a gradient placeholder */
  background-image:
    linear-gradient(
      to bottom,
      hsl(0 0% 40%),
      hsl(0 0% 20%)
    );
}

المساحة الفارغة في أعلى وأسفل الصفحة

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

لتحقيق تنسيق التمرير من الحافة إلى الحافة الذي يتوافق مع أسلوب الخط وخطوط التنسيق، استخدِم padding الذي يتطابق مع scroll-padding:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}

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

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

لخداع المتصفّحات لوضع الحشو في نهاية شريط التمرير، سأستهدف آخر رقم في كل قائمة وأُلحق عنصرًا زائفًا يمثّل مقدار الحشو المطلوب.

.horizontal-media-scroller > li:last-of-type figure {
  position: relative;

  &::after {
    content: "";
    position: absolute;

    inline-size: var(--gap);
    block-size: 100%;

    inset-block-start: 0;
    inset-inline-end: calc(var(--gap) * -1);
  }
}

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

محاذاة مواضع التمرير

يمكن أن تصبح حاوية التمرير التي تتضمّن عناصر متعدّدة خارج حدود الصفحة إطار عرض سريع التبديل باستخدام سطر واحد من CSS، ويصبح على العناصر تحديد كيفية محاذاة المحتوى مع إطار العرض هذا.

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block-end: calc(var(--gap) / 2);

  scroll-snap-type: inline mandatory;

  & figure {
    scroll-snap-align: start;
  }
}

التركيز

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

.horizontal-media-scroller a {
  outline-offset: 12px;

  &:focus {
    outline-offset: 7px;
  }

  @media (prefers-reduced-motion: no-preference) {
    & {
      transition: outline-offset .25s ease;
    }
  }
}

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

مؤشر التنقّل

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

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

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

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

يطلب هذا العرض التوضيحي من المستند المطلوب لتمريره، ويستدعي كل منهم الدالة rovingIndex(). نقْل العنصر rovingIndex() للحصول على تجربة التنقّل، مثل حاوية قائمة ووسيط اختيار طلب بحث مستهدَف، في حال لم تكن استهدافات التركيز من نسل مباشر.

document.querySelectorAll('.horizontal-media-scroller')
  .forEach(scroller =>
    rovingIndex({
      element: scroller,
      target: 'a',
}))

للاطّلاع على مزيد من المعلومات عن هذا التأثير، يمكنك الاطّلاع على مكتبة المصدر المفتوح roving-ux.

نسبة العرض إلى الارتفاع

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

يتم عرض صندوق نسبته 4:4 بجانب نسب التصميم الأخرى المستخدَمة التي تبلغ 16:9
و4:3.

@supports (aspect-ratio: 1) {
  .horizontal-media-scroller figure > picture {
    inline-size: auto; /* for a block-size driven ratio */
    aspect-ratio: 1; /* boxes by default */

    @nest section:nth-child(2) & {
      aspect-ratio: 16/9;
    }

    @nest section:nth-child(3) & {
      /* double the size of the others */
      block-size: calc(var(--size) * 2);
      aspect-ratio: 4/3;

      /* adjust size to fit more items into the viewport */
      @media (width <= 480px) {
        block-size: calc(var(--size) * 1.5);
      }
    }
  }
}

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

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

يفضّل استخدام بيانات أقل

على الرغم من أنّ هذه التقنية التالية لا تتوفّر إلا بعد تفعيل علامة في Canary، أردت أن أشارك معك كيفية توفير قدر كبير من وقت تحميل الصفحة و استخدام البيانات باستخدام بضعة أسطر من CSS. يسمح طلب الوسائط prefers-reduced-data من المستوى 5 بسؤال ما إذا كان الجهاز في أي حالات بيانات مخفضة، مثل وضع "توفير البيانات". إذا كان الأمر كذلك، يمكنني تعديل المستند، وفي هذه الحالة، إخفاء الصور.

ALT_TEXT_HERE

figure {
  @media (prefers-reduced-data: reduce) {
    & {
      min-inline-size: var(--size);

      & > picture {
        display: none;
      }
    }
  }
}

سيظلّ بالإمكان التنقّل في المحتوى بدون الحاجة إلى تنزيل الصور الكبيرة. في ما يلي الموقع الإلكتروني قبل إضافة prefers-reduced-data CSS:

(7 طلبات، 100 كيلوبايت من الموارد في 131 مللي ثانية)

ALT_TEXT_HERE

في ما يلي أداء الموقع الإلكتروني بعد إضافة ملف CSS الخاص بـ prefers-reduced-data:

ALT_TEXT_HERE

(71 طلبًا، و1.2 ميغابايت من الموارد في 1.07 ثانية)

64 طلبًا أقل، أي ما يعادل 60 صورة تقريبًا ضمن مساحة العرض (تم إجراء الاختبارات على شاشة عريضة) في علامة التبويب هذه للمتصفّح، وزيادة في سرعة تحميل الصفحة بنسبة %80 تقريبًا، و10% من البيانات التي يتم نقلها عبر الإنترنت خدمة مقارنة أسعار فعّالة جدًا

الخاتمة

والآن بعد أن عرفت كيف فعلت ذلك، كيف حالك؟! 🙂

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

المصدر

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

ما مِن عناصر للاطّلاع عليها هنا حتى الآن.