TL;DR
พร็อพเพอร์ตี้ CSS overscroll-behavior ช่วยให้นักพัฒนาซอฟต์แวร์ลบล้างลักษณะการเลื่อนแบบโอเวอร์โฟลว์เริ่มต้นของเบราว์เซอร์เมื่อถึงด้านบน/ด้านล่างของเนื้อหาได้ กรณีการใช้งานรวมถึงการปิดใช้ฟีเจอร์ดึงเพื่อรีเฟรชบนอุปกรณ์เคลื่อนที่ การนำเอฟเฟกต์การเรืองแสงเมื่อเลื่อนเกินและการยืดหดออก และการป้องกันไม่ให้เนื้อหาของหน้าเลื่อนเมื่ออยู่ใต้โมดัล/การวางซ้อน
ฉากหลัง
ขอบเขตการเลื่อนและการเชื่อมโยงการเลื่อน
การเลื่อนเป็นวิธีพื้นฐานที่สุดวิธีหนึ่งในการโต้ตอบกับหน้าเว็บ แต่รูปแบบ UX บางอย่างอาจจัดการได้ยากเนื่องจากลักษณะการทำงานเริ่มต้นที่แปลกประหลาดของเบราว์เซอร์ ตัวอย่างเช่น หน้าที่รวมแอปทั้งหมดซึ่งมีรายการจำนวนมากที่ผู้ใช้อาจต้องเลื่อนดู เมื่อเลื่อนถึงด้านล่าง คอนเทนเนอร์ที่ล้นจะหยุดเลื่อนเนื่องจากไม่มีเนื้อหาให้ดูอีก กล่าวคือ ผู้ใช้ไปถึง "ขอบเขตการเลื่อน" แต่สังเกตสิ่งที่เกิดขึ้นหากผู้ใช้เลื่อนต่อไป เนื้อหาด้านหลังลิ้นชักจะเริ่มเลื่อน คอนเทนเนอร์หลักจะควบคุมการเลื่อน ซึ่งในตัวอย่างนี้คือหน้าหลัก
ลักษณะการทำงานนี้เรียกว่าการต่อเชื่อมการเลื่อน ซึ่งเป็นลักษณะการทำงานเริ่มต้นของเบราว์เซอร์เมื่อเลื่อนเนื้อหา บ่อยครั้งที่ค่าเริ่มต้นนั้นค่อนข้างดี แต่บางครั้งก็ไม่เป็นที่ต้องการหรือไม่คาดคิด แอปบางแอปอาจต้องการมอบประสบการณ์ของผู้ใช้ที่แตกต่างออกไปเมื่อผู้ใช้เลื่อนไปถึงขอบเขตการเลื่อน
เอฟเฟกต์ดึงเพื่อรีเฟรช
การดึงเพื่อรีเฟรชเป็นท่าทางสัมผัสที่ใช้งานง่ายซึ่งได้รับความนิยมจากแอปบนอุปกรณ์เคลื่อนที่ เช่น Facebook และ Twitter การดึงฟีดโซเชียลลงมาแล้วปล่อยจะสร้างพื้นที่ใหม่สำหรับโหลดโพสต์ล่าสุดเพิ่มเติม อันที่จริงแล้ว UX นี้ได้รับความนิยมอย่างมากจนเบราว์เซอร์บนมือถืออย่าง Chrome บน Android ได้นำเอฟเฟกต์เดียวกันนี้มาใช้ การปัดลงที่ด้านบนของหน้าจะเป็นการรีเฟรชทั้งหน้า
เมื่อรีเฟรชฟีดใน PWA
จะรีเฟรชทั้งหน้า
สำหรับสถานการณ์อย่าง PWA ของ Twitter การปิดใช้การดำเนินการดึงเพื่อรีเฟรชแบบเนทีฟอาจเป็นเรื่องที่สมเหตุสมผล ทำไมจึงเป็นเช่นนั้น ในแอปนี้ คุณอาจไม่ต้องการให้ผู้ใช้รีเฟรชหน้าเว็บโดยไม่ตั้งใจ นอกจากนี้ คุณยังอาจเห็นภาพเคลื่อนไหวการรีเฟรช 2 ครั้งด้วย หรืออาจจะดีกว่าหากปรับแต่งการทำงานของเบราว์เซอร์ให้สอดคล้องกับการสร้างแบรนด์ของเว็บไซต์มากขึ้น แต่ข้อเสียคือการปรับแต่งประเภทนี้ทำได้ยาก นักพัฒนาซอฟต์แวร์จึงต้องเขียน JavaScript ที่ไม่จำเป็น เพิ่ม Listener การสัมผัสแบบไม่พาสซีฟ (ซึ่งบล็อกการเลื่อน) หรือติดทั้งหน้าไว้ใน <div> 100vw/vh (เพื่อป้องกันไม่ให้หน้าล้น) วิธีแก้ปัญหาเหล่านี้มีผลเสียที่ได้รับการบันทึกไว้อย่างดีต่อประสิทธิภาพการเลื่อน
เราทำได้ดีกว่านี้
ขอแนะนำ overscroll-behavior
พร็อพเพอร์ตี้ overscroll-behavior เป็นฟีเจอร์ CSS ใหม่ที่ควบคุมลักษณะการทำงานเมื่อคุณเลื่อนคอนเทนเนอร์ (รวมถึงหน้าเว็บ) มากเกินไป คุณสามารถใช้เพื่อยกเลิกการเชื่อมโยงการเลื่อน ปิดใช้/ปรับแต่งการดึงเพื่อรีเฟรช ปิดใช้เอฟเฟกต์ Rubberbanding ใน iOS (เมื่อ Safari ใช้ overscroll-behavior) และอื่นๆ
ส่วนที่ดีที่สุดคือการใช้ overscroll-behavior ไม่ส่งผลเสียต่อประสิทธิภาพของหน้าเว็บเหมือนกับแฮ็กที่กล่าวถึงในบทนำ
พร็อพเพอร์ตี้มีค่าที่เป็นไปได้ 3 ค่า ได้แก่
- auto - ค่าเริ่มต้น การเลื่อนที่เริ่มต้นในองค์ประกอบอาจส่งต่อไปยังองค์ประกอบระดับบนสุด
- contain - ป้องกันการเชื่อมโยงการเลื่อน การเลื่อนจะไม่ส่งต่อไปยังระดับบนสุด
แต่จะแสดงผลเฉพาะที่ภายในโหนด เช่น เอฟเฟกต์แสงเรืองเมื่อเลื่อนเกินขอบเขตใน Android หรือเอฟเฟกต์ยางยืดใน iOS ซึ่งจะแจ้งให้ผู้ใช้ทราบเมื่อเลื่อนถึงขอบเขตการเลื่อน หมายเหตุ: การใช้
overscroll-behavior: containในองค์ประกอบhtmlจะป้องกันการดำเนินการนำทางแบบ Overscroll - none - เหมือนกับ
containแต่ยังป้องกันเอฟเฟกต์การเลื่อนเกินภายในโหนดเองด้วย (เช่น แสงเรืองเมื่อเลื่อนเกินของ Android หรือการเลื่อนเกินแบบยางยืดของ iOS)
มาดูตัวอย่างการใช้ overscroll-behavior กัน
ป้องกันไม่ให้การเลื่อนหลุดออกจากองค์ประกอบตำแหน่งคงที่
สถานการณ์ของ Chatbox
ลองพิจารณาช่องแชทที่มีตำแหน่งคงที่ซึ่งอยู่ด้านล่างของหน้า โดยมีจุดประสงค์เพื่อให้กล่องแชทเป็นคอมโพเนนต์แบบสมบูรณ์ในตัวและเลื่อนแยกจากเนื้อหาที่อยู่เบื้องหลัง อย่างไรก็ตาม เนื่องจากการเชื่อมโยงการเลื่อน เอกสารจึงเริ่มเลื่อนทันทีที่ผู้ใช้ไปถึงข้อความสุดท้ายในประวัติการแชท
สำหรับแอปนี้ การเลื่อนที่เริ่มต้นภายในกล่องแชทควรอยู่ภายในแชท เราสามารถทำได้โดยเพิ่ม overscroll-behavior: contain ลงในองค์ประกอบที่มีข้อความแชท ดังนี้
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
โดยพื้นฐานแล้ว เรากำลังสร้างการแยกเชิงตรรกะระหว่างบริบทการเลื่อนของกล่องแชทกับหน้าหลัก ผลลัพธ์ที่ได้คือหน้าหลักจะยังคงอยู่เมื่อผู้ใช้เลื่อนไปถึงด้านบน/ด้านล่างของประวัติการแชท ม้วนคัมภีร์ที่เริ่มในกล่องแชทจะไม่กระจายออกไป
สถานการณ์การวางซ้อนหน้าเว็บ
อีกรูปแบบหนึ่งของสถานการณ์ "การเลื่อนไม่ถึง" คือเมื่อคุณเห็นเนื้อหาเลื่อนอยู่ด้านหลังภาพซ้อนทับตำแหน่งคงที่ ได้เวลาแจกของรางวัล
overscroll-behavior แล้ว เบราว์เซอร์พยายามช่วยเหลือ แต่กลับทำให้เว็บไซต์ดูมีข้อบกพร่อง
ตัวอย่าง - โมดัลที่มีและไม่มี overscroll-behavior: contain:
การปิดใช้การดึงเพื่อรีเฟรช
การปิดการดำเนินการดึงเพื่อรีเฟรชคือ CSS บรรทัดเดียว เพียงป้องกันไม่ให้เกิดการเชื่อมโยงการเลื่อนในองค์ประกอบที่กำหนดวิวพอร์ตทั้งหมด ในกรณีส่วนใหญ่จะเป็น <html> หรือ <body> ดังนี้
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
การเพิ่มโค้ดง่ายๆ นี้ช่วยให้เราแก้ไขภาพเคลื่อนไหวแบบดึงเพื่อรีเฟรชซ้ำในเดโมแชทบ็อกซ์ได้ และสามารถใช้เอฟเฟกต์ที่กำหนดเองซึ่งใช้ภาพเคลื่อนไหวการโหลดที่เรียบร้อยกว่าแทนได้ กล่องจดหมายทั้งหมดจะเบลอเมื่อรีเฟรชกล่องจดหมายด้วย
ตัวอย่างโค้ดแบบเต็มมีดังนี้
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refre>she<r"
div class=&qu><ot;l>oad<ing-bar"/div
div>< cla>ss=<"loading-bar"></div>
<div class="loading><-bar>&<quot>;/<div
div class=&q><uot;loading><-bar&quo>t;</div
/>div
section id="inbox"!-- msgs --/section
script
let _startY;
const inbox = document.querySel>ector('#inbox');
inbox.addEventListener('touchstart', e = {
_startY = e.touches>[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e = {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container&&
> // and &&user is scrolling up.
if (document.scrollingElement.scrollTop === 0 y _startY
!document.body.class<List.co>ntains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
/script
การปิดใช้เอฟเฟกต์การเรืองแสงและการยืดหยุ่นเมื่อเลื่อนเกินขอบเขต
หากต้องการปิดใช้เอฟเฟกต์การเด้งเมื่อถึงขอบเขตการเลื่อน ให้ใช้ overscroll-behavior-y: none ดังนี้
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
การสาธิตแบบเต็ม
เมื่อนำมารวมกัน เดโมกล่องแชทแบบเต็มจะใช้ overscroll-behavior เพื่อสร้างภาพเคลื่อนไหวแบบดึงเพื่อรีเฟรชที่กำหนดเองและปิดใช้การเลื่อนเพื่อไม่ให้หลุดออกจากวิดเจ็ตกล่องแชท ซึ่งจะมอบประสบการณ์ของผู้ใช้ที่ดีที่สุดซึ่งอาจทำได้ยากหากไม่มี CSS overscroll-behavior