องค์ประกอบที่รับรู้ตำแหน่งการเลื่อน

ภาพรวม

ปรับปรุงประสบการณ์ของผู้ใช้เกี่ยวกับปุ่มลอย เช่น ลิงก์ "กลับไปด้านบน" โดยแสดงเฉพาะเมื่อมีประโยชน์ คู่มือนี้จะแสดงวิธีสร้างองค์ประกอบเหล่านี้โดยใช้ CSS container-scroll-state-queries ซึ่งช่วยให้จัดสไตล์องค์ประกอบตามตำแหน่งการเลื่อนของคอนเทนเนอร์ได้โดยไม่ต้องอาศัย Listener หรือ Observer การเลื่อนของ 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);
}