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

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

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

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

إذا كنت تفضّل مشاهدة الفيديوهات، يمكنك الاطّلاع على نسخة من هذه المشاركة على 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 مرنًا بما يكفي للتعامل مع العديد من التركيبات المثيرة للاهتمام.

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

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

.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;
  }
}

التركيز

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

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

باستخدام تنسيق 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، وسأضيفه إلى قسم "الريمكسات التي أنشأها المجتمع" أدناه.

المصدر

الريمكسات التي أنشأها المستخدمون

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