ป๊อปอัป: ส่วนขยายเหล่านี้กลับมาได้รับความนิยมอีกครั้ง

ใหม่

เป้าหมายของโครงการริเริ่ม UI แบบเปิดคือการช่วยให้นักพัฒนาแอปสร้างประสบการณ์การใช้งานที่ยอดเยี่ยมได้ง่ายขึ้น โดยเราพยายามจัดการกับรูปแบบที่นักพัฒนาแอปพบปัญหามากขึ้น ซึ่งทำได้ด้วยการจัดหา API และคอมโพเนนต์ที่ฝังอยู่ในแพลตฟอร์มที่ดีขึ้น

ปัญหาหนึ่งๆ ดังกล่าวคือป๊อปอัป ซึ่งอธิบายใน UI แบบเปิดว่าเป็น "ป๊อปอัป"

โปปอัปมีชื่อเสียงที่ค่อนข้างแตกต่างกันมาอย่างยาวนาน ส่วนหนึ่งเป็นเพราะวิธีสร้างและติดตั้งใช้งาน การสร้างรูปแบบนี้ให้มีประสิทธิภาพนั้นไม่ใช่เรื่องง่าย แต่สามารถสร้างคุณค่าได้มากมายด้วยการนําผู้ใช้ไปยังสิ่งต่างๆ หรือทําให้ผู้ใช้รับรู้ถึงเนื้อหาในเว็บไซต์ โดยเฉพาะเมื่อใช้อย่างมีรสนิยม

การสร้างป๊อปอัปมักมีข้อกังวลหลักๆ 2 ข้อดังนี้

  • วิธีตรวจสอบว่าเนื้อหาแสดงอยู่เหนือเนื้อหาอื่นๆ ในตำแหน่งที่เหมาะสม
  • วิธีทำให้เข้าถึงได้ (ใช้งานกับแป้นพิมพ์ได้ โฟกัสได้ เป็นต้น)

Popover API ในตัวมีเป้าหมายที่หลากหลาย แต่ทั้งหมดมีเป้าหมายหลักเดียวกันคือช่วยให้นักพัฒนาแอปสร้างรูปแบบนี้ได้ง่ายๆ เป้าหมายที่โดดเด่น ได้แก่

  • ช่วยให้การแสดงองค์ประกอบและองค์ประกอบย่อยเหนือส่วนอื่นๆ ของเอกสารเป็นเรื่องง่าย
  • ทำให้เข้าถึงได้
  • ไม่ต้องใช้ JavaScript สําหรับลักษณะการทํางานทั่วไปส่วนใหญ่ (การปิดไฟ รายการเดี่ยว การซ้อน และอื่นๆ)

ดูข้อกําหนดเฉพาะทั้งหมดสําหรับป๊อปอัปได้ในเว็บไซต์ OpenUI

ความเข้ากันได้กับเบราว์เซอร์

คุณใช้ Popover API ในตัวได้ที่ไหนในตอนนี้ ฟีเจอร์นี้รองรับใน Chrome Canary ภายใต้ Flag "ฟีเจอร์แพลตฟอร์มบนเว็บเวอร์ชันทดลอง" ณ เวลาที่เขียนบทความนี้

หากต้องการเปิดใช้ Flag ดังกล่าว ให้เปิด Chrome Canary แล้วไปที่ chrome://flags จากนั้นเปิดใช้การติดธง "ฟีเจอร์แพลตฟอร์มเว็บเวอร์ชันทดลอง"

นอกจากนี้ยังมีช่วงทดลองใช้ Origin สำหรับนักพัฒนาแอปที่ต้องการทดสอบฟีเจอร์นี้ในสภาพแวดล้อมเวอร์ชันที่ใช้งานจริงด้วย

สุดท้ายคือ polyfill ที่อยู่ระหว่างการพัฒนาสําหรับ API อย่าลืมดูที่พื้นที่เก็บข้อมูล github.com/oddbird/popup-polyfill

คุณตรวจสอบการรองรับป๊อปอัปได้โดยใช้สิ่งต่อไปนี้

const supported = HTMLElement.prototype.hasOwnProperty("popover");

โซลูชันปัจจุบัน

ตอนนี้คุณทำอะไรได้บ้างเพื่อโปรโมตเนื้อหาให้โดดเด่นกว่าสิ่งอื่นๆ หากเบราว์เซอร์รองรับ คุณสามารถใช้องค์ประกอบกล่องโต้ตอบ HTML คุณต้องใช้ในแบบฟอร์ม "Modal" ซึ่งต้องใช้ JavaScript

Dialog.showModal();

มีข้อควรพิจารณาบางอย่างเกี่ยวกับการช่วยเหลือพิเศษ ขอแนะนําให้ใช้ a11y-dialog เช่น หากรองรับผู้ใช้ Safari เวอร์ชันต่ำกว่า 15.4

นอกจากนี้ คุณยังใช้ไลบรารีแบบป๊อปอัป การแจ้งเตือน หรือเคล็ดลับเครื่องมือที่มีอยู่มากมายได้อีกด้วย เครื่องมือเหล่านี้ส่วนใหญ่มักจะทํางานในลักษณะที่คล้ายกัน

  • ต่อคอนเทนเนอร์บางส่วนต่อท้ายเนื้อหาเพื่อแสดงป๊อปอัป
  • จัดรูปแบบให้อยู่เหนือสิ่งอื่นๆ
  • สร้างองค์ประกอบและต่อท้ายคอนเทนเนอร์เพื่อแสดงป๊อปอัป
  • ซ่อนโดยนําองค์ประกอบ popover ออกจาก DOM

ซึ่งต้องใช้ทรัพยากรเพิ่มเติมและนักพัฒนาแอปต้องตัดสินใจมากขึ้น นอกจากนี้ คุณยังต้องหาข้อมูลเพื่อค้นหาข้อเสนอที่รวมทุกอย่างที่คุณต้องการ Popover API มีไว้เพื่อรองรับสถานการณ์ต่างๆ ซึ่งรวมถึงเคล็ดลับเครื่องมือ โดยมีเป้าหมายเพื่อครอบคลุมสถานการณ์ทั่วไปทั้งหมด ซึ่งช่วยให้นักพัฒนาแอปไม่ต้องตัดสินใจอีกรอบเพื่อที่จะได้มุ่งเน้นสร้างประสบการณ์การใช้งาน

ป๊อปอัปแรก

เพียงเท่านี้คุณก็พร้อมใช้งาน

<div id="my-first-popover" popover>Popover Content!</div>
<button popovertoggletarget="my-first-popover">Toggle Popover</button>

แต่เกิดอะไรขึ้นที่นี่

  • คุณไม่จำเป็นต้องใส่องค์ประกอบป๊อปอัปลงในคอนเทนเนอร์หรืออะไรก็ตาม องค์ประกอบจะซ่อนอยู่โดยค่าเริ่มต้น
  • คุณไม่จําเป็นต้องเขียน JavaScript เพื่อทําให้ปรากฏ ซึ่งแอตทริบิวต์ popovertoggletarget จะจัดการ
  • เมื่อปรากฏขึ้น ระบบจะเลื่อนชั้นไปยังเลเยอร์บนสุด ซึ่งหมายความว่าระบบจะโปรโมตรายการดังกล่าวเหนือ document ในวิวพอร์ต คุณไม่จําเป็นต้องจัดการ z-index หรือกังวลเกี่ยวกับตําแหน่ง popover ใน DOM องค์ประกอบอาจฝังลึกอยู่ใน DOM โดยมีบรรพบุรุษที่ตัดออก นอกจากนี้ คุณยังดูองค์ประกอบที่อยู่ในเลเยอร์บนสุดได้ผ่านเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ ดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์บนสุดได้ในบทความนี้

GIF ที่แสดงการสาธิตการรองรับเลเยอร์บนสุดของเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์

  • คุณจะได้รับ "ปิดไฟ" ที่ใช้งานได้ทันที หมายความว่าคุณสามารถปิดป๊อปอัปด้วยสัญญาณปิด เช่น การคลิกนอกป๊อปอัป การนำทางด้วยแป้นพิมพ์ไปยังองค์ประกอบอื่น หรือกดแป้น 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 หรือ 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;
}

เคล็ดลับคือจัดกลุ่มทรานซิชันและภาพเคลื่อนไหวไว้ภายใต้ Media Query สำหรับการเคลื่อนไหว ซึ่งจะช่วยรักษาเวลาของคุณไว้ด้วย เนื่องจากคุณแชร์ค่าระหว่าง popover กับ ::backdrop ผ่านพร็อพเพอร์ตี้ที่กำหนดเองไม่ได้

@media(prefers-reduced-motion: no-preference) {
  [popover] { transition: transform 0.2s; }
  [popover]::backdrop { transition: opacity 0.2s; }
}

จนถึงตอนนี้ คุณได้ดูการใช้ popovertoggletarget เพื่อแสดงป๊อปอัปแล้ว เราใช้ "Light dismiss" เพื่อปิด แต่คุณจะใช้แอตทริบิวต์ 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 เพื่อโพลีฟีลฟังก์ชันการทำงานนั้นได้

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

สำหรับการจัดการโฟกัส คุณสามารถใช้แอตทริบิวต์โฟกัสอัตโนมัติเพื่อย้ายโฟกัสไปยังองค์ประกอบภายในป๊อปอัปได้ ซึ่งเหมือนกับ Dialog แต่ความแตกต่างจะเกิดขึ้นเมื่อโฟกัสกลับมาอีกครั้ง และนั่นเป็นเพราะการปิดแบบเบา ในกรณีส่วนใหญ่ การปิดป๊อปอัปจะเปลี่ยนโฟกัสกลับไปที่องค์ประกอบที่เคยโฟกัสไว้ก่อนหน้านี้ แต่โฟกัสจะย้ายไปยังองค์ประกอบที่คลิกเมื่อปิดไฟ หากองค์ประกอบนั้นรับโฟกัสได้ ดูส่วนเกี่ยวกับการจัดการโฟกัสในคําอธิบาย

คุณจะต้องเปิด "เวอร์ชันเต็มหน้าจอ" ของเดโมนี้เพื่อดูวิธีการทํางาน

ในการสาธิตนี้ องค์ประกอบที่มีโฟกัสจะมีเส้นขอบสีเขียว ลองกด Tab ไปยังส่วนต่างๆ ของอินเทอร์เฟซด้วยแป้นพิมพ์ สังเกตตําแหน่งที่โฟกัสจะกลับมาเมื่อปิดป๊อปอัป นอกจากนี้ คุณอาจสังเกตเห็นว่าหากกด Tab ไปรอบๆ หน้าจอ ป๊อปอัปจะปิดลง การดำเนินการนี้เป็นไปตามการออกแบบ แม้ว่าป๊อปอัปจะมีการจัดการโฟกัส แต่ก็ไม่ได้กักเก็บโฟกัสไว้ และการนำทางด้วยแป้นพิมพ์จะระบุสัญญาณการปิดเมื่อโฟกัสออกจากป๊อปอัป

การยึด (อยู่ระหว่างการพัฒนา)

รูปแบบที่จัดการได้ยากสำหรับป๊อปอัปคือการยึดองค์ประกอบกับทริกเกอร์ เช่น หากตั้งค่าเคล็ดลับเครื่องมือให้แสดงเหนือทริกเกอร์ แต่มีการเลื่อนเอกสาร เคล็ดลับเครื่องมือนั้นอาจถูกตัดออกโดยวิวพอร์ต ปัจจุบันมีข้อเสนอ JavaScript ที่จัดการกับปัญหานี้ได้ เช่น "UI ที่ลอยอยู่" เครื่องมือนี้จะจัดตำแหน่งเคล็ดลับเครื่องมือใหม่ให้คุณเพื่อหยุดไม่ให้เหตุการณ์นี้เกิดขึ้นและยึดตามลําดับตําแหน่งที่ต้องการ

แต่เราต้องการให้คุณกำหนดค่านี้ด้วยสไตล์ของคุณ ขณะนี้เรากำลังพัฒนา API เสริมควบคู่ไปกับ Popover API เพื่อจัดการปัญหานี้ API "การกำหนดตำแหน่งองค์ประกอบยึดของ CSS" จะช่วยให้คุณเชื่อมโยงองค์ประกอบกับองค์ประกอบอื่นๆ ได้ และจะดำเนินการในลักษณะที่ปรับตำแหน่งองค์ประกอบใหม่เพื่อไม่ให้ถูกตัดออกโดยวิวพอร์ต

การสาธิตนี้ใช้ 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

ข้อความโทสต์

การสาธิตนี้ใช้เลเยอร์ด้านบนเพื่อแสดงการแจ้งเตือนสไตล์ข้อความ Toast

  • รายการแบบป๊อปอัป 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 เพื่อให้ป๊อปอัปดังกล่าวอยู่ด้านบน

ป๊อปอัปของแผ่นงานการดำเนินการ

การสาธิตนี้แสดงวิธีใช้ป๊อปอัปเป็นเมนูการดำเนินการ

  • แสดงป๊อปอัปโดยค่าเริ่มต้นซึ่งลบล้าง display
  • แผงการดำเนินการเปิดขึ้นด้วยทริกเกอร์ป๊อปอัป
  • เมื่อแสดงป๊อปอัป ระบบจะเลื่อนป๊อปอัปไปยังเลเยอร์บนสุดและแปลเป็นมุมมอง
  • คุณใช้การปิดไฟเพื่อแสดงข้อความอีกครั้งได้

ป๊อปอัปที่เปิดใช้งานด้วยแป้นพิมพ์

การสาธิตนี้แสดงวิธีใช้ป๊อปอัปสำหรับ UI สไตล์พาเล็ตคำสั่ง

  • ใช้ cmd + j เพื่อแสดงป๊อปอัป
  • input โฟกัสด้วย autofocus
  • ช่องตัวเลือกเป็น popover ตัวที่ 2 ซึ่งอยู่ใต้อินพุตหลัก
  • การปิดแบบเบาจะปิดพ Palet ในกรณีที่ไม่มีเมนูแบบเลื่อนลง
  • ผู้สมัครรายอื่นสําหรับ Anchoring API

ป๊อปอัปที่กำหนดเวลา

การสาธิตนี้แสดงป๊อปอัป "ไม่มีการใช้งาน" หลังจากผ่านไป 4 วินาที รูปแบบ UI ที่มักใช้ในแอปที่มีข้อมูลผู้ใช้ที่ปลอดภัยเพื่อแสดงโมดัลการออกจากระบบ

  • ใช้ JavaScript เพื่อแสดงป๊อปอัปหลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง
  • รีเซ็ตตัวจับเวลาในการแสดงป๊อปอัป

โปรแกรมรักษาหน้าจอ

คุณสามารถเพิ่มลูกเล่นเล็กๆ น้อยๆ ลงในเว็บไซต์และเพิ่มโปรแกรมรักษาหน้าจอได้ เช่นเดียวกับในตัวอย่างก่อนหน้านี้

  • ใช้ JavaScript เพื่อแสดงป๊อปอัปหลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่ง
  • ปิดไฟเพื่อซ่อนและรีเซ็ตตัวจับเวลา

การติดตามเคอร์เซอร์ข้อความ

การสาธิตนี้แสดงวิธีทำให้ป๊อปอัปติดตามเคอร์เซอร์อินพุต

  • แสดงป๊อปอัปตามการเลือก เหตุการณ์สำคัญ หรือการป้อนอักขระพิเศษ
  • ใช้ JavaScript เพื่ออัปเดตตําแหน่งป๊อปอัปด้วยพร็อพเพอร์ตี้ที่กําหนดเองระดับขอบเขต
  • รูปแบบนี้ต้องคำนึงถึงเนื้อหาที่แสดงและความสามารถในการเข้าถึง
  • ซึ่งมักพบใน UI การแก้ไขข้อความและแอปที่คุณสามารถติดแท็กได้

เมนูปุ่มการทำงานแบบลอย

การสาธิตนี้แสดงวิธีใช้ป๊อปอัปเพื่อติดตั้งใช้งานเมนูปุ่มการดำเนินการแบบลอยตัวโดยไม่ต้องใช้ JavaScript

  • โปรโมตป๊อปอัปประเภท manual ด้วยเมธอด showPopover นี่คือปุ่มหลัก
  • เมนูคือป๊อปอัปอีกรายการหนึ่งที่เป็นเป้าหมายของปุ่มหลัก
  • เปิดเมนูด้วย popovertoggletarget
  • ใช้ autofocus เพื่อโฟกัสรายการเมนูแรกที่แสดงอยู่
  • การปิดไฟจะปิดเมนู
  • การบิดไอคอนใช้ :has() อ่านข้อมูลเพิ่มเติมเกี่ยวกับ :has() ได้ในบทความนี้

เท่านี้ก็เรียบร้อย

นี่เป็นข้อมูลเบื้องต้นเกี่ยวกับป๊อปอัปที่จะเปิดตัวในเร็วๆ นี้โดยเป็นส่วนหนึ่งของโครงการริเริ่ม UI แบบเปิด เมื่อใช้อย่างเหมาะสม ฟีเจอร์นี้จะเป็นส่วนเสริมที่ยอดเยี่ยมสำหรับแพลตฟอร์มเว็บ

อย่าลืมดูUI แบบเปิด คำอธิบายแบบป๊อปอัปจะอัปเดตอยู่เสมอเมื่อ API พัฒนาไป และนี่คือคอลเล็กชันสำหรับเดโมทั้งหมด

ขอขอบคุณที่แวะมา


รูปภาพโดย Madison Oren ใน Unsplash