عناصر تدرك موضع الانتقال

نظرة عامة

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

التنفيذ

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

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

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

2. تنسيق العنصر العائم

ضَع العنصر داخل الحاوية ونظِّم مظهره. يجب أن يكون مخفيًا تلقائيًا.

.back-to-top {
  position: sticky;
  bottom: 20px;
  visibility: hidden;
  opacity: 0;
  translate: 0 20px;
  transition:
    visibility 0.3s,
    opacity 0.3s ease,
    translate 0.3s ease;
}

3- الاستجابة لحالة الانتقال

استخدِم القاعدة @container مع الدالة scroll-state. للتحقّق مما إذا كان المستخدم قد انتقل للأسفل، تحقّق مما إذا كان يمكن الانتقال للأعلى في الحاوية.

/* When the container can be scrolled toward the top, it means the user has scrolled down */
@container scroll-state(scrollable: top) {
  .back-to-top {
    visibility: visible;
    opacity: 1;
    translate: 0 0;
  }
}

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

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

إذا لم تكن السمة container-scroll-state-queries متوافقة، سيظل العنصر العائم غير مرئي بسبب السمة التلقائية visibility: hidden. لضمان عمل العنصر، يمكنك اختيار جعله مرئيًا دائمًا في المتصفّحات غير المتوافقة.

/* Fallback for browsers that do not support the feature */
.back-to-top {
  visibility: visible; /* Always visible */
  opacity: 1;
}

/* Override for supported browsers to handle dynamic visibility */
@supports (container-type: scroll-state) {
  .back-to-top {
    visibility: hidden;
    opacity: 0;
  }
  
  @container scroll-state(scrollable: top) {
    .back-to-top {
      visibility: visible;
      opacity: 1;
      translate: 0 0;
    }
  }
}

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

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

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

.scrolled .back-to-top {
  visibility: visible;
  opacity: 1;
  translate: 0 0;
}
if (!CSS.supports('container-type', 'scroll-state')) {
  const sentinel = document.querySelector('.scroll-sentinel');
  const scroller = document.querySelector('.scroller');

  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      // If the sentinel is NOT intersecting, it means the user has scrolled down
      if (!entry.isIntersecting) {
        scroller.classList.add('scrolled');
      } else {
        scroller.classList.remove('scrolled');
      }
    });
  }, { root: scroller });

  observer.observe(sentinel);
}