تلميحات حول إمكانية التنقّل في الصفحة

نظرة عامة

تساعد التلميحات المرئية، مثل الظلال أو التدرجات، المستخدمين على فهم أنّه يمكنهم الانتقال للأسفل للاطّلاع على المزيد من المحتوى. يوضّح هذا الدليل كيفية إنشاء هذه التلميحات باستخدام CSS container-scroll-state-queries، ما يتيح تصميم العناصر استنادًا إلى حالة الحاوية القابلة للتمرير بدون الاعتماد على أدوات الاستماع أو المراقبة للتمرير في JavaScript.

التنفيذ

1. إنشاء حاوية التمرير

يجب تعريف حاوية الانتقال على أنّها حاوية طلبات حالة الانتقال.

.scroller {
  overflow-y: auto;
  /* Establish this element as a scroll-state query container */
  container-type: scroll-state;
  position: relative;
}

2. تنسيق المؤشرات

ضَع عناصر المؤشر (مثل الظلال أو التدرجات أو الأسهم) داخل الحاوية وصمِّمها. بشكل تلقائي، يجب ألا تكون مرئية. وعند عرضها، يجب ألا تكون تفاعلية، وذلك من خلال ضبط السمة pointer-events: none.

.indicator-top, .indicator-bottom {
  position: sticky;
  left: 0;
  right: 0;
  height: 20px;
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none; /* Let clicks pass through */
}

.indicator-top {
  top: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}

.indicator-bottom {
  bottom: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}

3- الاستعلام عن حالة الانتقال

استخدِم القاعدة @container مع الدالة scroll-state. يتحقّق هذا الإجراء مما إذا كان يمكن الانتقال للأعلى أو للأسفل في الحاوية لعرض المؤشر المعنيّ.

/* Show top indicator when the user can scroll up */
@container scroll-state(scrollable: top) {
  .indicator-top {
    opacity: 1;
  }
}

/* Show bottom indicator when the user can scroll down */
@container scroll-state(scrollable: bottom) {
  .indicator-bottom {
    opacity: 1;
  }
}

استراتيجيات احتياطية

الخيار الاحتياطي الأساسي

إذا لم تكن الميزة متاحة، ستبقى المؤشرات غير مرئية. بما أنّ هذه تلميحات وليست مهمة للوظائف، من المقبول حذفها في المتصفحات غير المتوافقة.

العنصر الاحتياطي المتقدّم (Intersection Observer)

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

<!-- Sentinel elements placed at the ends of the scroller -->
<div class="sentinel-top"></div>
<!-- Content goes here -->
<div class="sentinel-bottom"></div>
/* Marker styling to ensure it does not affect layout */
.sentinel-top, .sentinel-bottom {
  height: 0;
  width: 0;
  visibility: hidden;
}

.scroller.scrolled-down .indicator-top {
  opacity: 1;
}

.scroller.can-scroll-down .indicator-bottom {
  opacity: 1;
}
if (!CSS.supports('container-type', 'scroll-state')) {
  const topSentinel = document.querySelector('.sentinel-top');
  const bottomSentinel = document.querySelector('.sentinel-bottom');
  const scroller = document.querySelector('.scroller');

  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.target === topSentinel) {
        // If top sentinel is not intersecting, we have scrolled down
        scroller.classList.toggle('scrolled-down', !entry.isIntersecting);
      }
      if (entry.target === bottomSentinel) {
        // If bottom sentinel is intersecting, we reached the bottom
        scroller.classList.toggle('can-scroll-down', !entry.isIntersecting);
      }
    });
  }, { root: scroller });

  observer.observe(topSentinel);
  observer.observe(bottomSentinel);
}