ส่วนหัวที่หดลงเมื่อเลื่อนเป็นรูปแบบ UI ทั่วไปที่องค์ประกอบส่วนหัวแบบคงที่ที่ด้านบนของหน้าจะเปลี่ยนเป็นขนาดเล็กลงอย่างราบรื่นเมื่อผู้ใช้เลื่อนลง เอฟเฟกต์นี้มักใช้เพื่อเพิ่มพื้นที่หน้าจอให้มากที่สุดสำหรับเนื้อหาหลัก โดยยังคงเข้าถึงองค์ประกอบการนำทางหรือจุดเด่นของสินค้าที่สำคัญได้ ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน CSS ช่วยให้คุณสร้างเอฟเฟกต์นี้ได้ด้วยวิธีที่ประกาศและมีประสิทธิภาพ โดยลิงก์ภาพเคลื่อนไหวกับตำแหน่งการเลื่อนของเอกสาร
วิธีการนำไปใช้งาน
วิธีสร้างส่วนหัวที่หดลงเมื่อเลื่อนมีดังนี้
สร้างส่วนหัวแบบคงที่: เริ่มต้นด้วยองค์ประกอบส่วนหัวที่คงที่ที่ด้านบนของหน้าและมีความสูงที่กำหนดไว้ล่วงหน้า
<header>HEADER</header>header { position: fixed; height: 200px; top: 0; left: 0; right: 0; }กำหนดภาพเคลื่อนไหวการหด: สร้างภาพเคลื่อนไหว CSS ที่เปลี่ยนความสูงของส่วนหัว
@keyframes shrink { to { height: 50px; } }ใช้ภาพเคลื่อนไหวและไทม์ไลน์การเลื่อน: แนบภาพเคลื่อนไหวกับส่วนหัวและใช้ฟังก์ชัน
scroll()เพื่อลิงก์กับตำแหน่งการเลื่อนของเอกสารheader { animation: shrink auto linear both; animation-timeline: scroll(block root); }ตั้งค่า
animation-range: ใช้พร็อพเพอร์ตี้animation-rangeเพื่อระบุระยะการเลื่อนที่ควรแสดงภาพเคลื่อนไหว เช่น หากต้องการย่อส่วนหัวเมื่อเลื่อนผ่าน 150 พิกเซลแรก ให้ใช้animation-range: 0px 150px;header { animation-range: 0px 150px; }
เคล็ดลับ: หากต้องการป้องกันไม่ให้เนื้อหาที่อยู่หลังส่วนหัวถูกบดบัง ให้เพิ่ม padding-top ลงใน body (หรือคอนเทนเนอร์เนื้อหาหลัก) ที่เท่ากับความสูงเริ่มต้นของส่วนหัว
เคล็ดลับ: หากต้องการให้เนื้อหาของหน้าเลื่อนไปพร้อมกับส่วนหัวที่หดลง ให้ตั้งค่า animation-range-end เป็นความแตกต่างระหว่างขนาดเริ่มต้นและขนาดสิ้นสุด วิธีนี้ช่วยให้มั่นใจว่าภาพเคลื่อนไหวจะเสร็จสมบูรณ์เมื่อส่วนหัวมีขนาดสุดท้ายพอดี ในการสาธิตนี้ ส่วนหัวจะหดจาก 200px เป็น 50px ดังนั้น animation-range-end จึงตั้งค่าเป็น 150px
โค้ดตัวอย่าง
@keyframes shrink {
to {
height: 50px;
}
}
header {
animation: shrink auto linear both;
animation-timeline: scroll(block root);
animation-range: 0px 150px;
}
แนวทางปฏิบัติแนะนำ
เมื่อใช้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน คุณควรทำตามแนวทางปฏิบัติแนะนำต่อไปนี้เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่นและเข้าถึงได้
- ควรรวมการตรวจหาฟีเจอร์: เบราว์เซอร์บางรายการไม่รองรับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน ใช้
@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%))เพื่อตรวจสอบการรองรับและระบุตัวเลือกสำรองสำหรับเบราว์เซอร์ที่ไม่รองรับ- ต้องรวมการตรวจสอบ
(animation-range: 0% 100%)ไว้ที่นี่เพื่อกรองเบราว์เซอร์ที่รองรับเพียงบางส่วนออก - อย่าใช้แพ็กเกจ
scroll-timeline-polyfillสำหรับกลยุทธ์สำรอง เนื่องจากฟีเจอร์ยังไม่สมบูรณ์และมีปัญหาที่ทราบอยู่แล้วจำนวนมาก - หากภาพเคลื่อนไหวถือเป็นเพียงการตกแต่ง ให้เลือกใช้การเพิ่มประสิทธิภาพแบบต่อเนื่อง และอย่าระบุทางเลือกสำรอง
- ต้องรวมการตรวจสอบ
- ควรเคารพค่ากำหนดของผู้ใช้: ผู้ใช้บางรายต้องการให้มีการเคลื่อนไหวน้อยลงบนเว็บ ใช้คิวรีสื่อ
prefers-reduced-motionเพื่อปิดใช้หรือลดภาพเคลื่อนไหวสำหรับผู้ใช้เหล่านี้ - ควรพยายามทำให้เฉพาะพร็อพเพอร์ตี้ CSS ที่มีประสิทธิภาพเคลื่อนไหว: เพื่อให้ภาพเคลื่อนไหวราบรื่นที่สุด ให้ใช้พร็อพเพอร์ตี้ที่เคลื่อนไหวซึ่งจัดการได้โดยเทรด Compositor ของเบราว์เซอร์ เช่น
transformและopacityการทำให้พร็อพเพอร์ตี้อื่นๆ เช่นwidthหรือheightเคลื่อนไหวอาจทำให้เกิดปัญหาด้านประสิทธิภาพ - ควรใช้ลำดับการประกาศที่ถูกต้อง: เมื่อใช้พร็อพเพอร์ตี้ชวเลข
animationให้ประกาศanimation-timelineและanimation-rangeหลังจากพร็อพเพอร์ตี้ดังกล่าวเพื่อป้องกันไม่ให้ชวเลขรีเซ็ตไทม์ไลน์
เมื่อใช้ฟังก์ชัน scroll() เพื่อสร้างภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน ให้ทำดังนี้
- ไม่บังคับ ระบุตัวเลื่อนอย่างชัดเจน: เมื่อไม่ได้กำหนดเป้าหมายตัวเลื่อนระดับบนสุดที่ใกล้ที่สุด ให้ระบุตัวเลื่อนที่ต้องการใช้อย่างชัดเจนด้วย
scroll(root)หรือscroll(self)- เมื่อ
root,nearestหรือselfไม่เพียงพอ ให้ใช้ scroll-timeline ที่มีชื่อ
- เมื่อ
- ไม่บังคับ ระบุแกนที่จะติดตามอย่างชัดเจน: เมื่อไม่ได้กำหนดเป้าหมายแกน
blockเริ่มต้น (เช่น ในแถบเลื่อนแนวนอน) ให้ระบุแกนที่จะติดตามอย่างชัดเจนด้วยscroll(block)หรือscroll(inline)
สำหรับกรณีการใช้งานนี้โดยเฉพาะ
- องค์ประกอบที่คุณทำให้เคลื่อนไหวต้องไม่ใช่
position: staticหรือposition: relativeเมื่อใช้เปอร์เซ็นต์ในanimation-range- เนื่องจากองค์ประกอบเหล่านั้นถือว่า "อยู่ในโฟลว์" การย่อองค์ประกอบเหล่านั้นขณะเลื่อนจะลดระยะทางการเลื่อนทั้งหมด ซึ่งส่งผลต่อค่าที่คำนวณได้ เช่น
10%ในการเลื่อน
- เนื่องจากองค์ประกอบเหล่านั้นถือว่า "อยู่ในโฟลว์" การย่อองค์ประกอบเหล่านั้นขณะเลื่อนจะลดระยะทางการเลื่อนทั้งหมด ซึ่งส่งผลต่อค่าที่คำนวณได้ เช่น
การรองรับเบราว์เซอร์และกลยุทธ์สำรอง
ดังนั้น โดยทั่วไปจึงต้องมีกลยุทธ์สำรอง
สำหรับเบราว์เซอร์ที่ไม่รองรับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน คุณสามารถใช้โหมดสำรองเพื่อสร้างเอฟเฟกต์ภาพขึ้นมาใหม่ได้ โดยปกติแล้ว ฟังก์ชันสำรองจะสร้างขึ้นด้วย Listener การเลื่อน (สำหรับเอฟเฟกต์ ScrollTimeline) หรือ IntersectionObserver API (สำหรับเอฟเฟกต์ ViewTimeline)
ในเบราว์เซอร์ที่มีการรองรับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนในตัว ให้ใช้การติดตั้งใช้งาน CSS แบบเนทีฟเสมอ เนื่องจากมีประสิทธิภาพมากกว่า
โปรดทราบว่าคุณไม่สามารถสร้างเอฟเฟกต์ทั้งหมดขึ้นมาใหม่ได้โดยใช้วิธีการสำรอง
สำหรับ Use Case นี้โดยเฉพาะ สคริปต์ต่อไปนี้จะใช้โหมดสำรองสำหรับเบราว์เซอร์ที่ไม่รองรับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน โดยจะใช้ Listener การเลื่อนเพื่อติดตามตำแหน่งการเลื่อนของเอกสารในระยะทาง 150px และอัปเดตความสูงของส่วนหัวตามนั้น
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: scroll()) and (animation-range: 0% 100%)')) {
const header = document.querySelector('header');
const initialHeight = 200;
const finalHeight = 50;
const scrollDistance = 150;
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const scrollPercent = Math.min(1, scrollY / scrollDistance);
const newHeight = initialHeight - (initialHeight - finalHeight) * scrollPercent;
header.style.height = `${newHeight}px`;
});
}