เผยแพร่: 27 มี.ค. 2026
การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตขององค์ประกอบช่วยให้การเปลี่ยนฉากมุมมองหลายรายการทำงานพร้อมกันได้ อนุญาตให้การเปลี่ยนฉากมุมมองที่กำลังดำเนินการอยู่ซ้อนอยู่ภายในอีกรายการหนึ่ง และแก้ไขปัญหา z-index ที่คุณอาจพบกับการเปลี่ยนฉากมุมมองที่กำหนดขอบเขตของเอกสาร ทั้งหมดนี้ในขณะที่ส่วนอื่นๆ ของหน้ายังคงโต้ตอบได้ อ่านคู่มือนี้เพื่อดูวิธีใช้
ความจำเป็นในการเปลี่ยนฉากที่มีมุมมองที่กำหนดขอบเขตแคบลง
เมื่อคุณเริ่มการเปลี่ยนมุมมองเอกสารเดียวกันด้วย document.startViewTransition() (หรือผ่านการเปลี่ยนมุมมองเอกสารที่เกี่ยวข้อง) เบราว์เซอร์จะกำหนดขอบเขตการเปลี่ยนมุมมองที่ได้ไปยังเอกสาร
หลังจากที่เรียกใช้ Callback ของการอัปเดตและเบราว์เซอร์ถ่ายภาพรวมขององค์ประกอบที่จำเป็นทั้งหมดแล้ว ::view-transitionภาพซ้อนทับที่ได้และโครงสร้างขององค์ประกอบเสมือนจะแนบไปกับองค์ประกอบ :root html ในตัวอย่างต่อไปนี้
html
├─ ::view-transition
│ └─ ::view-transition-group(root)
│ └─ ::view-transition-image-pair(root)
│ ├─ ::view-transition-old(root)
│ └─ ::view-transition-new(root)
├─ head
└─ body
└─ …
เนื่องจากเลเยอร์ ::view-transition แสดงผลอยู่เหนือรูทของการเปลี่ยน จึงอาจทำให้เกิดสถานการณ์ที่ไม่คาดคิด เช่น องค์ประกอบที่เข้าร่วมการเปลี่ยนมุมมองอาจซ้อนทับกับองค์ประกอบอื่นๆ ที่ไม่ได้เข้าร่วมอย่างกะทันหัน หรือองค์ประกอบอาจไม่ถูกตัดโดยองค์ประกอบ Wrapper บรรพบุรุษอีกต่อไปในระหว่างการเปลี่ยนมุมมอง
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
การเปิดใช้ pointer-events อีกครั้งใน ::view-transition หรือการใช้กลุ่มการเปลี่ยนฉากมุมมองที่ซ้อนกันจะช่วยแก้ผลข้างเคียงบางอย่างที่การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตเอกสารทำให้เกิดได้ อย่างไรก็ตาม วิธีการเหล่านี้ไม่สามารถแก้ปัญหาได้ทั้งหมด
ตัวอย่างเช่น องค์ประกอบที่มี position: fixed หรือป๊อปโอเวอร์ยังคงถูกบดบังโดยการเปลี่ยนฉากมุมมองที่กำหนดขอบเขตเอกสารในขณะที่การเปลี่ยนฉากทำงานอยู่ ซึ่งเรียกอีกอย่างว่าปัญหา z-index
สลับป๊อปโอเวอร์ในเดโมต่อไปนี้ แล้วเลือกปุ่มสับเปลี่ยนเพื่อเริ่มการเปลี่ยนมุมมองระดับเอกสาร กลุ่มการเปลี่ยนมุมมองที่ซ้อนกันจะช่วยแก้ปัญหาการตัด แต่ปัญหาการซ้อนทับยังคงอยู่
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
วิธีแก้ปัญหาอย่างหนึ่งคือการจับภาพ popover เป็นส่วนหนึ่งของการเปลี่ยนมุมมองโดยการกำหนด view-transition-name ให้ แม้ว่าวิธีนี้อาจใช้ได้กับอินสแตนซ์เดียว แต่ก็ดูแลรักษายากและทำให้กระบวนการสร้าง Snapshot ทำงานหนักโดยไม่จำเป็น
การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตขององค์ประกอบ
การเปลี่ยนมุมมองที่กำหนดขอบเขตองค์ประกอบช่วยให้คุณเริ่มการเปลี่ยนมุมมองในส่วนย่อยของ DOM ได้ แทนที่จะเรียก document.startViewTransition() คุณจะเรียก element.startViewTransition() ในองค์ประกอบใดก็ได้ ซึ่งจะกำหนดขอบเขตการเปลี่ยนฉากของมุมมองไปยังองค์ประกอบนั้น
ในข้อมูลโค้ดต่อไปนี้ เบราว์เซอร์จะเริ่มการเปลี่ยนภาพมุมมองที่กำหนดขอบเขตองค์ประกอบในองค์ประกอบ <ul>
document.querySelector('ul').startViewTransition({
callback: () => {
// … code that manipulates the contents of <ul>
},
})
องค์ประกอบที่คุณเรียกใช้ element.startViewTransition() เช่น <ul> เรียกว่ารูทการเปลี่ยนฉากหรือขอบเขต
เมื่อเบราว์เซอร์กำหนดขอบเขตการเปลี่ยนมุมมองเป็นองค์ประกอบ ระบบจะแยกองค์ประกอบนั้นออกจาก DOM ที่เหลือ
- เบราว์เซอร์จะมองหาองค์ประกอบที่จะถ่ายภาพสแนปชอตภายในแผนผังย่อยของขอบเขตเท่านั้น
- ในระหว่างกระบวนการสร้างสแนปชอต ขณะที่เรียกใช้ Callback
updateจะมีเพียงการแสดงผลขอบเขตเท่านั้นที่หยุดชั่วคราว ::view-transitionที่ได้จะแทรกลงในรูทของการเปลี่ยน
ตัวอย่างเช่น เมื่อใช้ <ul> แผนผัง DOM จะมีลักษณะดังนี้ขณะที่การเปลี่ยนฉากของมุมมองทำงานอยู่
html
├─ head
└─ body
├─ ul
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(root)
│ │ ├─ ::view-transition-group-children(root)
│ │ │ └─ …
│ │ └─ ::view-transition-image-pair(root)
│ │ ├─ ::view-transition-old(root)
│ │ └─ ::view-transition-new(root)
│ ├─ li
│ ├─ li
│ └─ li
├─ button#showpopover
├─ button#reorder
└─ div#popover
└─ p
::view-transition Pseudo มีขนาดและรูปร่างเหมือนกับรูทของการเปลี่ยนฉาก และแสดงผลเฉพาะที่ด้านบนของรูทของการเปลี่ยนฉาก ด้วยเหตุนี้ ระบบจึงจะพิจารณาลำดับเลเยอร์ขององค์ประกอบที่อยู่นอกรูทของการเปลี่ยนฉาก
ตัวอย่างเช่น หากคุณมีป๊อปโอเวอร์ที่มองเห็นได้เหนือองค์ประกอบ <ul> แล้วเริ่มการเปลี่ยนฉากที่กำหนดขอบเขตองค์ประกอบในองค์ประกอบ <ul> ป๊อปโอเวอร์จะไม่ถูกบดบังโดยต้นไม้เสมือนของการเปลี่ยนฉาก
ลองใช้ในการสาธิตต่อไปนี้ โดยมีปุ่ม 2 ปุ่ม ปุ่มแรกจะสลับป๊อปโอเวอร์ และปุ่มที่ 2 จะจัดเรียงรายการใหม่โดยใช้การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตขององค์ประกอบ
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
เนื่องจากใช้การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตขององค์ประกอบ ป๊อปโอเวอร์จึงยังคงปรากฏที่ด้านบนขององค์ประกอบ <ul> ขณะที่การเปลี่ยนฉากทำงานอยู่
นอกจากนี้ องค์ประกอบที่อยู่นอกองค์ประกอบ <ul> เช่น ปุ่ม จะยังคงโต้ตอบได้ เนื่องจากองค์ประกอบเหล่านั้นไม่ได้เป็นส่วนหนึ่งของขอบเขต
ขอบเขตการเข้าร่วมด้วยตนเองและกลุ่มการเปลี่ยนภาพที่ซ้อนกัน
เมื่อเริ่มการเปลี่ยนฉากมุมมองที่กำหนดขอบเขตองค์ประกอบในองค์ประกอบที่คลิปส่วนที่เกิน (กล่าวคือ เมื่อตั้งค่า overflow เป็น hidden, scroll หรือ clip) คุณจะเห็นว่าเนื้อหาของการเปลี่ยนฉากมุมมองยังคงถูกคลิปไว้
เนื่องจากการเปลี่ยนฉากมุมมองระดับองค์ประกอบจะจัดการสิ่งต่อไปนี้โดยอัตโนมัติ
- ขอบเขตจะ
view-transition-name: rootมีผลโดยอัตโนมัติ ซึ่งทำให้ขอบเขตนั้นเข้าร่วมได้ด้วยตนเอง - ระบบจะใช้ขอบเขต
view-transition-group: containโดยอัตโนมัติเพื่อเปิดใช้กลุ่มการเปลี่ยนฉากมุมมองที่ซ้อนกัน ::view-transition-group-children(root)เสมือนที่ได้จะตัดเนื้อหาโดยอัตโนมัติโดยใช้overflow: clipหากรูทขอบเขตตัดส่วนที่เกิน ซึ่งจะป้องกันไม่ให้เสมือนแสดงภาพนอกรูทการเปลี่ยน
ด้วยเหตุนี้ คุณจึงสามารถใช้ CSS กับการเปลี่ยนมุมมองที่กำหนดขอบเขตองค์ประกอบโดยเน้นเฉพาะองค์ประกอบที่ต้องการจับภาพได้ ตัวอย่างเช่น ในการสาธิตรายการ CSS จะเพิ่มเฉพาะชื่อลงในรายการ
ul li {
view-transition-name: match-element;
view-transition-class: album;
}
ลองใช้ในการสาธิตต่อไปนี้ ซึ่งจะช่วยให้คุณลบล้างการเข้าร่วมด้วยตนเองได้ เมื่อขอบเขตเป็นการเข้าร่วมด้วยตนเอง (ลักษณะการทำงานเริ่มต้น) ทุกอย่างจะทำงานตามที่คาดไว้ เมื่อขอบเขตไม่ได้มีส่วนร่วมด้วยตนเอง ขอบเขตจะเปลี่ยนทันที และเนื้อหาจะล้นออกมาจาก Wrapper ในระหว่างการเปลี่ยน
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
เพื่อเป็นข้อมูลอ้างอิง ต้นไม้แบบจำลองสำหรับการสาธิตนี้ที่มีการเข้าร่วมด้วยตนเองจะมีลักษณะดังนี้
html
├─ head
└─ body
├─ ul
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(root)
│ │ ├─ ::view-transition-group-children(root)
│ │ │ ├─ ::view-transition-group(item1)
│ │ │ │ └─ ::view-transition-image-pair(item1)
│ │ │ │ ├─ ::view-transition-old(item1)
│ │ │ │ └─ ::view-transition-new(item1)
│ │ │ ├─ ::view-transition-group(item2)
│ │ │ │ └─ …
│ │ │ …
│ │ └─ ::view-transition-image-pair(root)
│ │ ├─ ::view-transition-old(root)
│ │ └─ ::view-transition-new(root)
│ ├─ li
│ ├─ li
│ └─ li
└─ button#reorder
เนื่องจากรูทของการเปลี่ยนฉาก ซึ่งก็คือองค์ประกอบ <ul> จะตัดเนื้อหาในแนวตั้ง ::view-transition-group-children(root) จึงใช้การตัดโดยอัตโนมัติด้วย
การเปลี่ยนภาพมุมมองที่กำหนดขอบเขตองค์ประกอบพร้อมกัน
เนื่องจากทรานซิชันมุมมองที่กำหนดขอบเขตองค์ประกอบจะทำงานแยกกัน ทรานซิชันมุมมองที่กำหนดขอบเขตองค์ประกอบหลายรายการจึงทำงานพร้อมกันได้หากมีขอบเขตต่างกัน
การสาธิตต่อไปนี้มีปุ่มจัดเรียงใหม่ 2 ปุ่ม ปุ่มละ 1 รายการ ปุ่มแต่ละปุ่มจะเริ่มการเปลี่ยนฉากมุมมองระดับองค์ประกอบในรายการที่เกี่ยวข้องเท่านั้น เนื่องจากแผนผัง DOM ของทั้ง 2 รายการไม่ทับซ้อนกัน การเปลี่ยนภาพมุมมองที่กำหนดขอบเขตขององค์ประกอบ 2 รายการจึงทำงานพร้อมกันได้โดยแยกกัน
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
ลักษณะการแยกนี้ยังช่วยให้คุณนําค่า view-transition-name ไปใช้ซ้ำในขอบเขตต่างๆ ได้ด้วย ตราบใดที่ชื่อยังคงไม่ซ้ำกันภายในขอบเขตของชื่อนั้น ก็จะไม่มีความขัดแย้ง
การเปลี่ยนฉากมุมมองที่กำหนดขอบเขตองค์ประกอบที่ซ้อนกันและการจำกัดการใช้ view-transition-name
เมื่อ DOM Tree ของการเปลี่ยนภาพที่กำหนดขอบเขตองค์ประกอบหลายรายการทับซ้อนกัน จะมีความเสี่ยงที่ค่า view-transition-name จะชนกัน ด้วยเหตุนี้ เบราว์เซอร์จึงกำหนด view-transition-scope: all ให้กับการเปลี่ยนภาพวิวที่กำหนดขอบเขตขององค์ประกอบที่ใช้งานอยู่โดยอัตโนมัติเพื่อลดความเสี่ยงนี้
พร็อพเพอร์ตี้ view-transition-scope ช่วยให้มั่นใจได้ว่าค่า view-transition-name จะอยู่ในขอบเขตของ Subtree ขององค์ประกอบ เช่นเดียวกับที่ anchor-scope กำหนดขอบเขตค่า anchor-name พร็อพเพอร์ตี้ยอมรับ none รายชื่อที่คุณต้องการกำหนดขอบเขต หรือ all เพื่อกำหนดขอบเขตค่าทั้งหมด
นอกจากจะป้องกันไม่ให้ชื่อหลุดออกมาแล้ว view-transition-scope ยังป้องกันไม่ให้องค์ประกอบและเนื้อหาขององค์ประกอบนั้นถูกจับภาพโดยการเปลี่ยนภาพวิวภายนอกที่เกิดขึ้นพร้อมกันด้วย เมื่อกระบวนการสร้างสแนปชอตข้ามผ่านซับทรีเพื่อค้นหาองค์ประกอบที่จะสร้างสแนปชอต ระบบจะไม่สนใจองค์ประกอบ (และซับทรีทั้งหมดขององค์ประกอบ) ที่ใช้ view-transition-scope: all ซึ่งถือว่าองค์ประกอบเหล่านั้นเข้าร่วมการเปลี่ยนฉากที่กำหนดขอบเขตองค์ประกอบอื่นอยู่แล้ว
การสาธิตต่อไปนี้เป็นการดัดแปลงจากการสาธิตก่อนหน้า นอกจากปุ่ม 2 ปุ่มที่สุ่มเนื้อหาในรายการแล้ว ยังมีปุ่มสลับเพื่อสลับรายการด้วย การสลับ.reversedชั้นเรียนใน#lists-wrapperจะจัดการการสลับ
การสาธิตการใช้งานแบบสด
การบันทึกการสาธิต
เนื่องจากview-transition-scope: allจะใช้โดยอัตโนมัติในระหว่างการเปลี่ยนฉากแบบสุ่ม คุณจึงเริ่มการเปลี่ยนฉากแบบสลับด้านนอกพร้อมกันได้ในขณะที่การเปลี่ยนฉากแบบสุ่มยังคงดำเนินอยู่
เนื่องจาก view-transition-scope: all ยังป้องกันไม่ให้มีการถ่ายภาพรวมขององค์ประกอบในการเปลี่ยนฉากภายนอกด้วย เดโมจึงเพิ่มค่า view-transition-name ลงในองค์ประกอบที่รวมองค์ประกอบ <ul> ด้วย
#list1-wrapper, #list2-wrapper {
view-transition-name: attr(id type(<custom-ident>));
}
แผนผังจำลองสำหรับการสาธิตนี้หลังจากเริ่มสุ่มในรายการที่ 2 แล้วสลับทั้ง 2 รายการจะมีลักษณะดังนี้
html
├─ head
└─ body
└─ #lists-wrapper.reversed (SCOPE)
├─ ::view-transition
│ └─ ::view-transition-group(lists-wrapper)
│ ├─ ::view-transition-group-children(lists-wrapper)
│ │ ├─ ::view-transition-group(list1-wrapper)
│ │ │ └─ ::view-transition-image-pair(list1-wrapper)
│ │ │ ├─ ::view-transition-old(list1-wrapper)
│ │ │ └─ ::view-transition-new(list1-wrapper)
│ │ └─ ::view-transition-group(list2-wrapper)
│ │ └─ ::view-transition-image-pair(list2-wrapper)
│ │ ├─ ::view-transition-old(list2-wrapper)
│ │ └─ ::view-transition-new(list2-wrapper)
│ └─ ::view-transition-image-pair(lists-wrapper)
│ ├─ ::view-transition-old(lists-wrapper)
│ └─ ::view-transition-new(lists-wrapper)
├─ div#list1-wrapper
│ ├─ ul
│ │ ├─ li#item1
│ │ ├─ li#item2
│ │ └─ li#item3
│ └─ button.reorder
└─ div#list2-wrapper
├─ ul (SCOPE)
│ ├─ ::view-transition
│ │ └─ ::view-transition-group(list)
│ │ ├─ ::view-transition-group-children(list )
│ │ │ ├─ ::view-transition-group(item4)
│ │ │ │ └─ ::view-transition-image-pair(item4)
│ │ │ │ ├─ ::view-transition-old(item4)
│ │ │ │ └─ ::view-transition-new(item4)
│ │ │ ├─ ::view-transition-group(item5)
│ │ │ │ └─ …
│ │ │ …
│ │ └─ ::view-transition-image-pair(list)
│ │ ├─ ::view-transition-old(list)
│ │ └─ ::view-transition-new(list)
│ ├─ li#item4
│ ├─ li#item5
│ └─ li#item6
└─ button.reorder
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนฉากของมุมมองที่กำหนดขอบเขตขององค์ประกอบได้ที่คำอธิบาย ข้อกำหนด css-view-transitions-2 และรายการการแก้ไขข้อกำหนดที่เปิดอยู่