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

ใหม่

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

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

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

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

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

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

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

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

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

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

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

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

สุดท้ายคือ 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


ก่อนที่จะดู Use Case ทั่วไปและตัวอย่าง เรามาดูกันสัก 2-3 ข้อกัน


ประเภทของป๊อปอัป

เราได้อธิบายลักษณะการโต้ตอบที่ไม่ใช่ 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

ขนมปังปิ้ง

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

  • รายการแบบป๊อปอัป 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 แบบเปิด เมื่อใช้อย่างเหมาะสม ฟีเจอร์นี้จะเป็นส่วนเสริมที่ยอดเยี่ยมสำหรับแพลตฟอร์มเว็บ

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

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


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