ใหม่แล้ว
เป้าหมายของโครงการริเริ่ม Open UI คือการช่วยให้นักพัฒนาแอปสร้างประสบการณ์ของผู้ใช้ที่ยอดเยี่ยมได้ง่ายขึ้น เราจึงพยายามจัดการกับรูปแบบที่มีปัญหามากขึ้นที่นักพัฒนาแอปพบ เราจะทำเช่นนี้ได้ด้วยการจัดหา API และคอมโพเนนต์ในตัวของแพลตฟอร์มที่ดีขึ้น
ปัญหาดังกล่าวอย่างหนึ่งคือป๊อปอัป ซึ่งอธิบายไว้ใน Open UI ว่าเป็น "ป๊อปโอเวอร์"
ป๊อปโอเวอร์มีชื่อเสียงที่ค่อนข้างแตกต่างกันมาเป็นเวลานาน ซึ่งส่วนหนึ่งเป็นเพราะวิธีการสร้างและติดตั้งใช้งาน แม้ว่าการสร้างรูปแบบนี้ให้ดีอาจไม่ใช่เรื่องง่าย แต่ก็สามารถสร้างคุณค่าได้มากด้วยการนำผู้ใช้ไปยังสิ่งต่างๆ หรือทำให้ผู้ใช้ทราบถึงเนื้อหาในเว็บไซต์ของคุณ โดยเฉพาะอย่างยิ่งเมื่อใช้ในลักษณะที่เหมาะสม
โดยปกติแล้วจะมีข้อกังวลหลัก 2 ประการเมื่อสร้างป๊อปโอเวอร์
- วิธีตรวจสอบว่าระบบจะวางโฆษณาเหนือเนื้อหาอื่นๆ ในตำแหน่งที่เหมาะสม
- วิธีทำให้เข้าถึงได้ (ใช้แป้นพิมพ์ได้ โฟกัสได้ และอื่นๆ)
Popover API ในตัวมีเป้าหมายที่หลากหลาย โดยมีเป้าหมายหลักเดียวกันคือการช่วยให้นักพัฒนาแอปสร้างรูปแบบนี้ได้ง่ายๆ เป้าหมายที่สำคัญมีดังนี้
- ช่วยให้แสดงองค์ประกอบและองค์ประกอบย่อยเหนือส่วนอื่นๆ ของเอกสารได้ง่าย
- ทำให้เข้าถึงได้ง่าย
- ไม่จำเป็นต้องใช้ JavaScript สำหรับลักษณะการทำงานที่พบบ่อยที่สุด (การปิดแบบเบา การแสดงผลแบบเดี่ยว การซ้อนกัน และอื่นๆ)
ดูรายละเอียดทั้งหมดเกี่ยวกับป๊อปอัปได้ในเว็บไซต์ OpenUI
ความเข้ากันได้กับเบราว์เซอร์
ตอนนี้คุณใช้ Popover API ในตัวได้ที่ใด โดยฟีเจอร์นี้รองรับใน Chrome Canary ที่อยู่เบื้องหลังค่าสถานะ "ฟีเจอร์แพลตฟอร์มบนเว็บเวอร์ชันทดลอง" ณ เวลาที่เขียนบทความนี้
หากต้องการเปิดใช้ Flag ดังกล่าว ให้เปิด Chrome Canary แล้วไปที่ chrome://flags จากนั้นเปิดใช้การติดธง "ฟีเจอร์แพลตฟอร์มเว็บเวอร์ชันทดลอง"
นอกจากนี้ยังมีOrigin Trial สำหรับนักพัฒนาแอปที่ต้องการทดสอบฟีเจอร์นี้ในสภาพแวดล้อมการใช้งานจริงด้วย
สุดท้ายนี้ เรากำลังพัฒนา polyfill สำหรับ API อย่าลืมดูที่เก็บข้อมูลที่ github.com/oddbird/popup-polyfill
คุณตรวจสอบการสนับสนุนแบบป๊อปอัปได้โดยทำดังนี้
const supported = HTMLElement.prototype.hasOwnProperty("popover");
โซลูชันปัจจุบัน
ปัจจุบันคุณทำอะไรได้บ้างเพื่อโปรโมตเนื้อหาของคุณเหนือสิ่งอื่นใด หากเบราว์เซอร์รองรับ คุณจะใช้องค์ประกอบ HTML Dialog ได้ คุณจะต้องใช้ในรูปแบบ "โมดัล" และต้องใช้ JavaScript จึงจะใช้งานได้
Dialog.showModal();
มีข้อควรพิจารณาบางประการเกี่ยวกับการช่วยเหลือพิเศษ ขอแนะนำให้ใช้ a11y-dialog เช่น หากรองรับผู้ใช้ Safari เวอร์ชันต่ำกว่า 15.4
หรือจะใช้ไลบรารีป๊อปโอเวอร์ การแจ้งเตือน หรือเคล็ดลับเครื่องมือที่มีอยู่มากมายก็ได้ ซึ่งส่วนใหญ่จะทำงานในลักษณะที่คล้ายกัน
- ต่อท้ายคอนเทนเนอร์บางรายการกับเนื้อหาเพื่อแสดงป๊อปโอเวอร์
- จัดรูปแบบให้วางอยู่เหนือทุกอย่าง
- สร้างองค์ประกอบและต่อท้ายคอนเทนเนอร์เพื่อแสดงป๊อปโอเวอร์
- ซ่อนโดยนำองค์ประกอบป๊อปโอเวอร์ออกจาก DOM
ซึ่งต้องมีทรัพยากร Dependency เพิ่มเติมและนักพัฒนาแอปต้องตัดสินใจมากขึ้น นอกจากนี้ คุณยังต้องค้นหาข้อเสนอที่ตอบโจทย์ทุกความต้องการด้วย Popover API มีจุดมุ่งหมายเพื่อรองรับหลายสถานการณ์ รวมถึงเคล็ดลับเครื่องมือ เป้าหมายคือการครอบคลุมสถานการณ์ทั่วไปทั้งหมดเหล่านั้น เพื่อช่วยให้นักพัฒนาแอปไม่ต้องตัดสินใจอีกต่อไปและสามารถมุ่งเน้นที่การสร้างประสบการณ์การใช้งานได้
ป๊อปอัปแรก
คุณต้องมีเพียงเท่านี้
<div id="my-first-popover" popover>Popover Content!</div>
<button popovertoggletarget="my-first-popover">Toggle Popover</button>
แต่เกิดอะไรขึ้นที่นี่
- คุณไม่จำเป็นต้องใส่องค์ประกอบป๊อปโอเวอร์ลงในคอนเทนเนอร์หรืออะไรก็ตาม เนื่องจากระบบจะซ่อนองค์ประกอบดังกล่าวโดยค่าเริ่มต้น
- คุณไม่จำเป็นต้องเขียน JavaScript ใดๆ เพื่อให้ปุ่มปรากฏ แอตทริบิวต์
popovertoggletargetจะจัดการเรื่องนี้ - เมื่อปรากฏขึ้น ระบบจะเลื่อนไปที่เลเยอร์บนสุด ซึ่งหมายความว่าวิดีโอจะได้รับการโปรโมตเหนือ
documentในวิวพอร์ต คุณไม่ต้องจัดการz-indexหรือกังวลว่าป๊อปโอเวอร์จะอยู่ที่ใดใน DOM ซึ่งอาจซ้อนกันลึกลงไปใน DOM โดยมีองค์ประกอบระดับบนสุดที่ครอบตัด นอกจากนี้ คุณยังดูได้ว่าองค์ประกอบใดอยู่ในเลเยอร์บนสุดในขณะนี้ผ่านเครื่องมือสำหรับนักพัฒนาเว็บ ดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์บนสุดได้ที่บทความนี้

- คุณจะได้รับ "ปิดอย่างรวดเร็ว" ทันที ซึ่งหมายความว่าคุณสามารถปิดป๊อปโอเวอร์ด้วยสัญญาณปิด เช่น การคลิกนอกป๊อปโอเวอร์ การไปยังองค์ประกอบอื่นด้วยแป้นพิมพ์ หรือการกดปุ่ม Esc เปิดแอปอีกครั้งแล้วลองใช้เลย
คุณจะได้รับอะไรอีกบ้างจากป๊อปโอเวอร์ มาดูตัวอย่างเพิ่มเติมกัน ลองดูการสาธิตนี้ที่มีเนื้อหาบางอย่างในหน้า
ปุ่มการทำงานแบบลอยนั้นมีตำแหน่งคงที่และมี z-index สูง
.fab {
position: fixed;
z-index: 99999;
}
เนื้อหาป๊อปโอเวอร์จะซ้อนอยู่ใน DOM แต่เมื่อคุณเปิดป๊อปโอเวอร์ ระบบจะเลื่อนเนื้อหาขึ้นไปเหนือองค์ประกอบที่มีตำแหน่งคงที่นั้น คุณไม่จำเป็นต้องตั้งค่าสไตล์ใดๆ
นอกจากนี้ คุณอาจสังเกตเห็นว่าป๊อปโอเวอร์มี::backdropองค์ประกอบเสมือนแล้ว องค์ประกอบทั้งหมดที่อยู่ในเลเยอร์บนสุดจะมี::backdropองค์ประกอบเสมือนที่จัดรูปแบบได้ ตัวอย่างนี้จัดรูปแบบ ::backdrop ด้วยสีพื้นหลังที่มีค่าอัลฟ่าลดลงและฟิลเตอร์ฉากหลัง ซึ่งจะเบลอเนื้อหาที่อยู่ด้านล่าง
การจัดรูปแบบป๊อปโอเวอร์
มาดูการจัดรูปแบบป๊อปโอเวอร์กัน โดยค่าเริ่มต้น ป๊อปโอเวอร์จะมีตำแหน่งคงที่และมีการเว้นระยะห่างบางส่วน นอกจากนี้ยังมี display: none คุณสามารถลบล้างการตั้งค่านี้เพื่อแสดงป๊อปโอเวอร์ได้ แต่การทำเช่นนั้นจะไม่เลื่อนแอปขึ้นไปที่เลเยอร์บนสุด
[popover] { display: block; }
ไม่ว่าคุณจะโปรโมตป๊อปโอเวอร์ด้วยวิธีใด เมื่อโปรโมตป๊อปโอเวอร์ไปยังเลเยอร์บนสุดแล้ว คุณอาจต้องจัดวางหรือกำหนดตำแหน่ง คุณไม่สามารถกำหนดเป้าหมายเลเยอร์บนสุดและทำสิ่งต่างๆ เช่น
:open {
display: grid;
place-items: center;
}
โดยค่าเริ่มต้น ป๊อปโอเวอร์จะจัดวางที่กึ่งกลางวิวพอร์ตโดยใช้ margin: auto แต่ในบางกรณี คุณอาจต้องการระบุตำแหน่งอย่างชัดเจน เช่น
[popover] {
top: 50%;
left: 50%;
translate: -50%;
}
หากต้องการจัดวางเนื้อหาภายในป๊อปโอเวอร์โดยใช้ CSS Grid หรือ Flexbox คุณอาจต้องห่อหุ้มเนื้อหานี้ในองค์ประกอบ ไม่เช่นนั้น คุณจะต้องประกาศกฎแยกต่างหากที่จะเปลี่ยน display เมื่อป๊อปโอเวอร์อยู่ในเลเยอร์บนสุด การตั้งค่าเป็นค่าเริ่มต้นจะทำให้แสดงโดยค่าเริ่มต้น ซึ่งจะลบล้าง display: none
[popover]:open {
display: flex;
}
หากคุณลองใช้เดโมดังกล่าว คุณจะเห็นว่าตอนนี้ป๊อปโอเวอร์จะเปลี่ยนเข้าและออก คุณเปลี่ยนป๊อปโอเวอร์เข้าและออกได้โดยใช้:openตัวเลือกเสมือน :openตัวเลือกเทียมจะตรงกับป๊อปโอเวอร์ที่แสดง (และอยู่ในเลเยอร์บนสุด)
ตัวอย่างนี้ใช้คุณสมบัติที่กำหนดเองเพื่อขับเคลื่อนการเปลี่ยนผ่าน และคุณยังใช้การเปลี่ยนกับ ::backdrop ของป๊อปโอเวอร์ได้ด้วย
[popover] {
--hide: 1;
transition: transform 0.2s;
transform: translateY(calc(var(--hide) * -100vh))
scale(calc(1 - var(--hide)));
}
[popover]::backdrop {
transition: opacity 0.2s;
opacity: calc(1 - var(--hide, 1));
}
[popover]:open::backdrop {
--hide: 0;
}
เคล็ดลับคือการจัดกลุ่มการเปลี่ยนภาพและภาพเคลื่อนไหวภายใต้การค้นหาสื่อสำหรับการเคลื่อนไหว ซึ่งจะช่วยให้คุณรักษาเวลาได้ด้วย เนื่องจากคุณแชร์ค่าระหว่าง popover กับ ::backdrop ผ่านพร็อพเพอร์ตี้ที่กําหนดเองไม่ได้
@media(prefers-reduced-motion: no-preference) {
[popover] { transition: transform 0.2s; }
[popover]::backdrop { transition: opacity 0.2s; }
}
จนถึงตอนนี้ คุณได้เห็นการใช้ popovertoggletarget เพื่อแสดงป๊อปโอเวอร์แล้ว เราใช้ "ปิดอย่างรวดเร็ว" เพื่อปิด แต่คุณยังได้รับแอตทริบิวต์ popovershowtarget และ popoverhidetarget ที่ใช้ได้ด้วย มาเพิ่มปุ่มในป๊อปโอเวอร์ที่ซ่อนป๊อปโอเวอร์นั้นและเปลี่ยนปุ่มเปิด/ปิดเพื่อใช้ popovershowtarget กัน
<div id="code-popover" popover>
<button popoverhidetarget="code-popover">Hide Code</button>
</div>
<button popovershowtarget="code-popover">Reveal Code</button>
ดังที่ได้กล่าวไปก่อนหน้านี้ว่า Popover API ครอบคลุมมากกว่าแนวคิดป๊อปอัปในอดีตของเรา คุณสามารถสร้างสำหรับสถานการณ์ทุกประเภท เช่น การแจ้งเตือน เมนู เคล็ดลับเครื่องมือ เป็นต้น
บางสถานการณ์เหล่านั้นต้องใช้รูปแบบการโต้ตอบที่แตกต่างกัน การโต้ตอบ เช่น การวางเมาส์ เราได้ทดลองใช้แอตทริบิวต์ popoverhovertarget แต่ยังไม่ได้นำมาใช้ในขณะนี้
<div popoverhovertarget="hover-popover">Hover for Code</div>
แนวคิดคือการวางเมาส์เหนือองค์ประกอบเพื่อแสดงเป้าหมาย คุณกำหนดค่าลักษณะการทำงานนี้ได้ผ่านพร็อพเพอร์ตี้ CSS พร็อพเพอร์ตี้ CSS เหล่านี้จะกำหนดช่วงเวลาสำหรับการวางเมาส์เหนือและออกจากองค์ประกอบที่ป๊อปโอเวอร์ตอบสนอง ลักษณะการทำงานเริ่มต้นที่ใช้ในการทดสอบคือการแสดงป๊อปโอเวอร์หลังจากที่ผู้ใช้0.5s:hoverอย่างชัดเจน จากนั้นจะต้องปิดด้วยการแตะด้านนอกหรือเปิดป๊อปโอเวอร์อื่นเพื่อปิด (ดูข้อมูลเพิ่มเติมได้ในส่วนถัดไป) ซึ่งเป็นเพราะระยะเวลาซ่อนป๊อปโอเวอร์ถูกตั้งค่าเป็น Infinity
ในระหว่างนี้ คุณสามารถใช้ JavaScript เพื่อ Polyfill ฟังก์ชันการทำงานดังกล่าวได้
let hoverTimer;
const HOVER_TRIGGERS = document.querySelectorAll("[popoverhovertarget]");
const tearDown = () => {
if (hoverTimer) clearTimeout(hoverTimer);
};
HOVER_TRIGGERS.forEach((trigger) => {
const popover = document.querySelector(
`#${trigger.getAttribute("popoverhovertarget")}`
);
trigger.addEventListener("pointerenter", () => {
hoverTimer = setTimeout(() => {
if (!popover.matches(":open")) popover.showPopover();
}, 500);
trigger.addEventListener("pointerleave", tearDown);
});
});
การตั้งค่าให้บางอย่างเป็นหน้าต่างการวางเมาส์ที่ชัดเจนมีประโยชน์ตรงที่ช่วยให้มั่นใจได้ว่าการกระทำของผู้ใช้เป็นไปโดยเจตนา (เช่น ผู้ใช้วางเคอร์เซอร์เหนือเป้าหมาย) เราไม่ต้องการแสดงป๊อปอัป เว้นแต่ผู้ใช้จะตั้งใจ
ลองใช้เดโมนี้ซึ่งคุณสามารถวางเมาส์เหนือเป้าหมายโดยตั้งค่าหน้าต่างเป็น 0.5s
ก่อนที่จะไปดูตัวอย่างกรณีการใช้งานที่พบบ่อย เรามาดูเรื่องต่างๆ กันก่อน
ประเภทของป๊อปโอเวอร์
เราได้กล่าวถึงลักษณะการทำงานของการโต้ตอบที่ไม่ใช่ JavaScript แล้ว แต่พฤติกรรมของป๊อปโอเวอร์โดยรวมล่ะ จะเกิดอะไรขึ้นหากคุณไม่ต้องการใช้ "ปิดอย่างรวดเร็ว" หรือต้องการใช้รูปแบบ Singleton กับป๊อปโอเวอร์
Popover API ช่วยให้คุณระบุป๊อปโอเวอร์ได้ 3 ประเภทซึ่งมีลักษณะการทำงานแตกต่างกัน
[popover=auto]/[popover]:
- การรองรับการซ้อน ซึ่งไม่ได้หมายถึงการซ้อนใน DOM เท่านั้น คำจำกัดความของป๊อปอัปบรรพบุรุษคือป๊อปอัปที่มีลักษณะดังนี้
- ที่เกี่ยวข้องตามตำแหน่ง DOM (องค์ประกอบย่อย)
- ที่เกี่ยวข้องโดยการทริกเกอร์แอตทริบิวต์ในองค์ประกอบย่อย เช่น
popovertoggletarget,popovershowtargetและอื่นๆ - ที่เกี่ยวข้องกับแอตทริบิวต์
anchor(ภายใต้การพัฒนา CSS Anchoring API)
- ปิดอย่างรวดเร็ว
- การเปิดจะปิดป๊อปโอเวอร์อื่นๆ ที่ไม่ใช่ป๊อปโอเวอร์บรรพบุรุษ ลองเล่นเดโมด้านล่างซึ่งไฮไลต์วิธีการซ้อนป๊อปโอเวอร์ขององค์ประกอบหลัก ดูว่าการเปลี่ยนอินสแตนซ์
popoverhidetarget/popovershowtargetบางรายการเป็นpopovertoggletargetจะเปลี่ยนแปลงสิ่งต่างๆ ได้อย่างไร - การปิดไฟดวงใดดวงหนึ่งจะปิดไฟทั้งหมด แต่การปิดไฟดวงใดดวงหนึ่งในกองจะปิดเฉพาะดวงที่อยู่เหนือขึ้นไปในกองเท่านั้น
[popover=manual]:
- ไม่ปิดป๊อปโอเวอร์อื่นๆ
- ปิดไม่ได้เมื่อแตะที่อื่น
- ต้องปิดอย่างชัดเจนผ่านองค์ประกอบทริกเกอร์หรือ JavaScript
JavaScript API
เมื่อต้องการควบคุมป๊อปโอเวอร์ได้มากขึ้น คุณสามารถใช้ JavaScript ได้ คุณจะได้รับทั้งวิธีshowPopoverและhidePopover นอกจากนี้ คุณยังฟังเหตุการณ์ popovershow และ popoverhide ได้ด้วย
แสดงป๊อปโอเวอร์
js
popoverElement.showPopover()
ซ่อนป๊อปโอเวอร์
popoverElement.hidePopover()
ฟังว่ามีการแสดงป๊อปโอเวอร์หรือไม่
popoverElement.addEventListener('popovershow', doSomethingWhenPopoverShows)
ฟังว่ามีการแสดงป๊อปโอเวอร์และยกเลิกการแสดงป๊อปโอเวอร์
popoverElement.addEventListener('popovershow',event => {
event.preventDefault();
console.warn(‘We blocked a popover from being shown’);
})
ฟังว่ามีการซ่อนป๊อปโอเวอร์หรือไม่
popoverElement.addEventListener('popoverhide', doSomethingWhenPopoverHides)
คุณยกเลิกการซ่อนป๊อปโอเวอร์ไม่ได้
popoverElement.addEventListener('popoverhide',event => {
event.preventDefault();
console.warn("You aren't allowed to cancel the hiding of a popover");
})
ตรวจสอบว่าป๊อปโอเวอร์อยู่ในเลเยอร์บนสุดหรือไม่ โดยทำดังนี้
popoverElement.matches(':open')
ซึ่งจะช่วยเพิ่มประสิทธิภาพในบางสถานการณ์ที่พบได้ไม่บ่อย เช่น แสดงป๊อปโอเวอร์หลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง
การสาธิตนี้มีป๊อปโอเวอร์ที่มีเสียงป๊อป ดังนั้นเราจึงต้องใช้ JavaScript เพื่อเล่นเสียง เมื่อคลิก เราจะซ่อนป๊อปโอเวอร์ เล่นเสียง แล้วแสดงป๊อปโอเวอร์อีกครั้ง
การช่วยเหลือพิเศษ
การช่วยเหลือพิเศษเป็นสิ่งสำคัญอันดับแรกในการพิจารณาเกี่ยวกับ Popover API การแมปการช่วยเหลือพิเศษจะเชื่อมโยงป๊อปโอเวอร์กับองค์ประกอบทริกเกอร์ตามที่จำเป็น ซึ่งหมายความว่าคุณไม่จำเป็นต้องประกาศแอตทริบิวต์ aria-* เช่น aria-haspopup หากคุณใช้แอตทริบิวต์ที่ทริกเกอร์รายการใดรายการหนึ่ง เช่น popovertoggletarget
สำหรับการจัดการโฟกัส คุณสามารถใช้แอตทริบิวต์ autofocus เพื่อย้ายโฟกัสไปยังองค์ประกอบภายในป๊อปโอเวอร์ได้ ซึ่งเหมือนกับ Dialog แต่จะแตกต่างกันเมื่อส่งคืนโฟกัส เนื่องจากมีการปิดด้วยการแตะนอกองค์ประกอบ ในกรณีส่วนใหญ่ การปิดป๊อปโอเวอร์จะคืนโฟกัสไปยังองค์ประกอบที่โฟกัสก่อนหน้านี้ แต่ระบบจะย้ายโฟกัสไปยังองค์ประกอบที่คลิกเมื่อปิดอย่างรวดเร็ว หากองค์ประกอบนั้นรับโฟกัสได้ ดูส่วนเกี่ยวกับการจัดการโฟกัสในคำอธิบาย
คุณจะต้องเปิด "เวอร์ชันเต็มหน้าจอ" ของการสาธิตนี้เพื่อดูการทำงาน
ในการสาธิตนี้ องค์ประกอบที่โฟกัสจะได้รับเส้นขอบสีเขียว ลองใช้แป้น Tab เพื่อไปยังส่วนต่างๆ ของอินเทอร์เฟซด้วยแป้นพิมพ์ โปรดทราบว่าระบบจะเปลี่ยนโฟกัสไปที่ใดเมื่อปิดป๊อปโอเวอร์ นอกจากนี้ คุณอาจสังเกตเห็นว่าหากกด Tab ไปเรื่อยๆ ป๊อปโอเวอร์จะปิด ระบบได้รับการออกแบบมาเช่นนี้ แม้ว่าป๊อปโอเวอร์จะมีการจัดการโฟกัส แต่ก็ไม่ได้ดักจับโฟกัส และการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์จะระบุสัญญาณปิดเมื่อโฟกัสย้ายออกจากป๊อปโอเวอร์
การยึด (อยู่ระหว่างการพัฒนา)
เมื่อพูดถึงป๊อปโอเวอร์ รูปแบบที่ซับซ้อนซึ่งต้องพิจารณาคือการยึดองค์ประกอบกับทริกเกอร์ เช่น หากตั้งค่าเคล็ดลับเครื่องมือให้แสดงเหนือทริกเกอร์ แต่เอกสารเลื่อนลง เคล็ดลับเครื่องมือดังกล่าวอาจถูกตัดออกโดยวิวพอร์ต ปัจจุบันมีข้อเสนอ JavaScript ที่ใช้จัดการปัญหานี้ เช่น "Floating UI" โดยจะเปลี่ยนตำแหน่งเคล็ดลับเครื่องมือเพื่อให้คุณหยุดไม่ให้เกิดเหตุการณ์นี้และใช้ลำดับตำแหน่งที่ต้องการ
แต่เราต้องการให้คุณกำหนดลักษณะนี้ด้วยสไตล์ของคุณเอง เรากำลังพัฒนา API ที่ทำงานร่วมกันกับ Popover API เพื่อจัดการปัญหานี้ API "การวางตำแหน่ง CSS Anchor" จะช่วยให้คุณเชื่อมโยงองค์ประกอบกับองค์ประกอบอื่นๆ ได้ และจะดำเนินการในลักษณะที่จัดตำแหน่งองค์ประกอบใหม่เพื่อไม่ให้ถูกตัดออกโดยวิวพอร์ต
การสาธิตนี้ใช้ Anchoring API ในสถานะปัจจุบัน ตำแหน่งของเรือจะตอบสนองต่อตำแหน่งของสมอในวิวพอร์ต
ต่อไปนี้คือตัวอย่าง CSS ที่ทำให้การสาธิตนี้ทำงานได้ ไม่ต้องใช้ JavaScript
.anchor {
--anchor-name: --anchor;
}
.anchored {
position: absolute;
position-fallback: --compass;
}
@position-fallback --compass {
@try {
bottom: anchor(--anchor top);
left: anchor(--anchor right);
}
@try {
top: anchor(--anchor bottom);
left: anchor(--anchor right);
}
}
คุณดูรายละเอียดได้ที่นี่ นอกจากนี้ยังมี Polyfill สำหรับ API นี้ด้วย
ตัวอย่าง
ตอนนี้คุณคงคุ้นเคยกับสิ่งที่ป๊อปโอเวอร์มีให้และวิธีใช้แล้ว มาดูตัวอย่างกัน
การแจ้งเตือน
การสาธิตนี้แสดงการแจ้งเตือน "คัดลอกไปยังคลิปบอร์ด"
- ใช้
[popover=manual] - เมื่อดำเนินการ ให้แสดงป๊อปโอเวอร์พร้อม
showPopover - หลังจาก
2000msหมดเวลา ให้ซ่อนด้วยhidePopover
ข้อความโทสต์
เดโมนี้ใช้ชั้นบนสุดเพื่อแสดงการแจ้งเตือนสไตล์ข้อความโทสต์
- ป๊อปโอเวอร์ 1 รายการที่มีประเภท
manualจะทำหน้าที่เป็นคอนเทนเนอร์ - ระบบจะเพิ่มการแจ้งเตือนใหม่ลงในป๊อปโอเวอร์และแสดงป๊อปโอเวอร์
- ระบบจะนำออกด้วย Web Animations API เมื่อคลิกและนำออกจาก DOM
- หากไม่มีข้อความป๊อปอัปให้แสดง ระบบจะซ่อนป๊อปโอเวอร์
เมนูแบบซ้อน
การสาธิตนี้แสดงให้เห็นว่าเมนูการนำทางแบบซ้อนอาจทำงานอย่างไร
- ใช้
[popover=auto]เนื่องจากอนุญาตให้ใช้ป๊อปโอเวอร์ที่ซ้อนกันได้ - ใช้
autofocusในลิงก์แรกของเมนูแบบเลื่อนลงแต่ละรายการเพื่อไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ - ซึ่งเหมาะอย่างยิ่งสำหรับ CSS Anchoring API แต่สำหรับการสาธิตนี้ คุณสามารถใช้ JavaScript จำนวนเล็กน้อยเพื่ออัปเดตตำแหน่งโดยใช้พร็อพเพอร์ตี้ที่กำหนดเอง
const ANCHOR = (anchor, anchored) => () => {
const { top, bottom, left, right } = anchor.getBoundingClientRect();
anchored.style.setProperty("--top", top);
anchored.style.setProperty("--right", right);
anchored.style.setProperty("--bottom", bottom);
anchored.style.setProperty("--left", left);
};
PRODUCTS_MENU.addEventListener("popovershow", ANCHOR(PRODUCT_TARGET, PRODUCTS_MENU));
โปรดทราบว่าเนื่องจากเดโมนี้ใช้ autofocus จึงต้องเปิดใน "มุมมองแบบเต็มหน้าจอ" เพื่อใช้การไปยังส่วนต่างๆ ด้วยแป้นพิมพ์
ป๊อปโอเวอร์สื่อ
การสาธิตนี้แสดงวิธีป๊อปอัปสื่อ
- ใช้
[popover=auto]เพื่อปิดอย่างรวดเร็ว - JavaScript จะรอฟังเหตุการณ์
playของวิดีโอและแสดงวิดีโอขึ้นมา - ป๊อปโอเวอร์
popoverhideจะหยุดวิดีโอชั่วคราว
ป๊อปโอเวอร์สไตล์ Wiki
การสาธิตนี้แสดงวิธีสร้างเคล็ดลับเครื่องมือเนื้อหาในบรรทัดที่มีสื่อ
- ใช้
[popover=auto]การแสดงรายการหนึ่งจะซ่อนรายการอื่นๆ เนื่องจากไม่ได้เป็นบรรพบุรุษ - แสดงใน
pointerenterด้วย JavaScript - อีกหนึ่งตัวอย่างที่เหมาะอย่างยิ่งสำหรับ CSS Anchoring API
ลิ้นชักการนำทาง
การสาธิตนี้สร้างลิ้นชักการนำทางโดยใช้ป๊อปโอเวอร์
- ใช้
[popover=auto]เพื่อปิดอย่างรวดเร็ว - ใช้
autofocusเพื่อโฟกัสรายการนำทางแรก
การจัดการฉากหลัง
การสาธิตนี้แสดงวิธีจัดการฉากหลังสำหรับป๊อปโอเวอร์หลายรายการในกรณีที่คุณต้องการให้ ::backdrop แสดงเพียงรายการเดียว
- ใช้ JavaScript เพื่อดูแลรายการป๊อปโอเวอร์ที่มองเห็นได้
- ใช้ชื่อคลาสกับป๊อปโอเวอร์ที่ต่ำที่สุดในเลเยอร์บนสุด
ป๊อปโอเวอร์เคอร์เซอร์ที่กำหนดเอง
การสาธิตนี้แสดงวิธีใช้ popover เพื่อเลื่อน canvas ไปยังเลเยอร์บนสุดและใช้เพื่อแสดงเคอร์เซอร์ที่กำหนดเอง
- โปรโมต
canvasไปยังเลเยอร์บนสุดด้วยshowPopoverและ[popover=manual] - เมื่อเปิดป๊อปโอเวอร์อื่นๆ ให้ซ่อนและแสดงป๊อปโอเวอร์
canvasเพื่อให้แน่ใจว่าป๊อปโอเวอร์นี้อยู่ด้านบน
ป๊อปอัป ActionSheet
การสาธิตนี้แสดงวิธีใช้ป๊อปโอเวอร์เป็นแผ่นการดำเนินการ
- แสดงป๊อปโอเวอร์โดยค่าเริ่มต้นโดยลบล้าง
display - ActionSheet จะเปิดขึ้นพร้อมทริกเกอร์ป๊อปโอเวอร์
- เมื่อแสดงป๊อปโอเวอร์ ระบบจะเลื่อนป๊อปโอเวอร์ไปที่เลเยอร์บนสุดและแปลเป็นมุมมอง
- คุณใช้การปิดอย่างรวดเร็วเพื่อกลับไปที่หน้าเดิมได้
ป๊อปโอเวอร์ที่เปิดใช้งานแป้นพิมพ์
การสาธิตนี้แสดงวิธีใช้ป๊อปโอเวอร์สำหรับ UI รูปแบบพาเล็ตคำสั่ง
- ใช้ cmd + j เพื่อแสดงป๊อปโอเวอร์
inputจะโฟกัสด้วยautofocus- ช่องตัวเลือกรวมคือกล่องที่ 2
popoverซึ่งอยู่ใต้ช่องป้อนข้อมูลหลัก - การปิดอย่างรวดเร็วจะปิดจานสีหากไม่มีเมนูแบบเลื่อนลง
- อีกตัวอย่างหนึ่งของ Anchoring API
ป๊อปอัปที่กำหนดเวลา
การสาธิตนี้แสดงป๊อปอัปการไม่มีการใช้งานหลังจากผ่านไป 4 วินาที รูปแบบ UI ที่มักใช้ในแอปที่มีข้อมูลที่ปลอดภัยเกี่ยวกับผู้ใช้เพื่อแสดงโมดอลการออกจากระบบ
- ใช้ JavaScript เพื่อแสดงป๊อปโอเวอร์หลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง
- รีเซ็ตตัวจับเวลาเมื่อแสดงป๊อปโอเวอร์
โปรแกรมรักษาหน้าจอ
คุณสามารถเพิ่มความแปลกใหม่ให้กับเว็บไซต์และเพิ่มโปรแกรมพักหน้าจอได้เช่นเดียวกับเดโมก่อนหน้า
- ใช้ JavaScript เพื่อแสดงป๊อปโอเวอร์หลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง
- ปัดเบาๆ เพื่อซ่อนและรีเซ็ตตัวจับเวลา
การติดตามเคอร์เซอร์ข้อความ
การสาธิตนี้แสดงวิธีทำให้ป๊อปโอเวอร์ติดตามเคอร์เซอร์ของอินพุต
- แสดงป๊อปโอเวอร์ตามการเลือก เหตุการณ์สำคัญ หรือการป้อนสัญลักษณ์พิเศษ
- ใช้ JavaScript เพื่ออัปเดตตำแหน่งป๊อปโอเวอร์ด้วยพร็อพเพอร์ตี้ที่กำหนดเองที่กำหนดขอบเขต
- รูปแบบนี้ต้องพิจารณาอย่างรอบคอบเกี่ยวกับเนื้อหาที่แสดงและการเข้าถึง
- โดยมักจะเห็นใน UI การแก้ไขข้อความและแอปที่คุณสามารถติดแท็กได้
เมนูปุ่มการทำงานแบบลอย
การสาธิตนี้แสดงวิธีใช้ป๊อปโอเวอร์เพื่อใช้เมนูของปุ่มการทำงานแบบลอยโดยไม่ต้องใช้ JavaScript
- โปรโมตป๊อปอัปประเภท
manualด้วยเมธอดshowPopoverนี่คือปุ่มหลัก - เมนูเป็นป๊อปโอเวอร์อีกรายการหนึ่งซึ่งเป็นเป้าหมายของปุ่มหลัก
- เปิดเมนูด้วย
popovertoggletarget - ใช้
autofocusเพื่อโฟกัสรายการเมนูแรกที่แสดง - การปิดแบบเบาจะปิดเมนู
- การบิดไอคอนใช้
:has()อ่านเพิ่มเติมเกี่ยวกับ:has()ได้ในบทความนี้
เท่านี้ก็เรียบร้อย
ดังนั้นนี่คือข้อมูลเบื้องต้นเกี่ยวกับป๊อปโอเวอร์ ซึ่งจะเปิดตัวในอนาคตเป็นส่วนหนึ่งของความคิดริเริ่ม Open UI หากใช้อย่างเหมาะสม ฟีเจอร์นี้จะเป็นส่วนเสริมที่ยอดเยี่ยมสำหรับแพลตฟอร์มเว็บ
อย่าลืมดู Open UI เราจะคอยอัปเดตคำอธิบายเกี่ยวกับป๊อปโอเวอร์อยู่เสมอเมื่อ API มีการเปลี่ยนแปลง และนี่คือคอลเล็กชันสำหรับการสาธิตทั้งหมด
ขอขอบคุณที่แวะมา