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

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

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

إصدار تجريبي

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

إنشاء تخطيط التمرير

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

يظهر صفان
مروران. ولا يحتوي أحدها على علامة حذف، مما يعني أنه أطول
وكل عنوان مقروء بالكامل. والآخر أقصر ويتم اقتطاع العديد
من العناوين بعلامة حذف.

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

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

سيظل المحتوى قابلاً للتنقّل، ولكن بدون تحمُّل تكلفة الصور الثقيلة التي يتم تنزيلها. في ما يلي الموقع الإلكتروني قبل إضافة خدمة مقارنة الأسعار (CSS) prefers-reduced-data:

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

ALT_TEXT_HERE

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

ALT_TEXT_HERE

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

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

الخلاصة

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

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

المصدر

ريمكسات من المنتدى

لا يتوفّر أي محتوى بعد.