Petunjuk Affordance Kemampuan Scroll

Ringkasan

Petunjuk visual, seperti bayangan atau gradien, membantu pengguna memahami bahwa mereka dapat men-scroll untuk melihat lebih banyak konten. Panduan ini menunjukkan cara membuat petunjuk ini menggunakan container-scroll-state-queries CSS, yang memungkinkan elemen gaya visual berdasarkan status container yang dapat di-scroll tanpa mengandalkan pemroses atau observer scroll JavaScript.

Penerapan

1. Membuat Penampung Scroll

Penampung scroll harus dideklarasikan sebagai penampung kueri status scroll.

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

2. Menentukan Gaya Indikator

Tempatkan elemen indikator (seperti bayangan, gradien, atau panah) di dalam penampung dan beri gaya. Secara default, setelan ini tidak akan terlihat. Saat ditampilkan, elemen tersebut tidak boleh interaktif, dengan menetapkan 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. Membuat kueri Status Scroll

Gunakan aturan @container dengan fungsi scroll-state. Periksa apakah penampung dapat di-scroll ke atas atau ke bawah untuk menampilkan indikator yang sesuai.

/* 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;
  }
}

Strategi penggantian

Penggantian Dasar

Jika fitur tidak didukung, indikator akan tetap tidak terlihat. Karena ini adalah petunjuk dan tidak penting untuk fungsionalitas, Anda dapat menghilangkannya di browser yang tidak didukung.

Penggantian Lanjutan (Intersection Observer)

Jika petunjuk diperlukan, gunakan IntersectionObserver untuk mengalihkan class saat elemen sentinel di bagian atas dan bawah scroller bergerak masuk dan keluar dari scrollport.

<!-- 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);
}