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

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

ปัญหาหนึ่งที่ว่านี้คือป๊อปอัป ซึ่งอธิบายไว้ใน UI แบบเปิดว่า "ป๊อปอัป"

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

การสร้างป๊อปอัปมักมีข้อกังวลหลัก 2 ประการ ได้แก่

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

Popover API ในตัวมีเป้าหมายที่หลากหลาย ซึ่งทั้งหมดมีเป้าหมายเดียวกันเพื่อให้นักพัฒนาซอฟต์แวร์สร้างรูปแบบนี้ได้ง่าย เป้าหมายที่สำคัญเหล่านั้น ได้แก่

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

คุณสามารถดูข้อกำหนดทั้งหมดของป๊อปอัปได้ที่เว็บไซต์ OpenUI

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

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

หากต้องการเปิดธงดังกล่าว ให้เปิด 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

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

  • เพิ่มภาชนะบางส่วนต่อท้ายเนื้อหาเพื่อแสดงป๊อปอัป
  • จัดรูปแบบให้ไว้เหนือทุกสิ่ง
  • สร้างองค์ประกอบแล้วนำไปต่อท้ายคอนเทนเนอร์เพื่อแสดงป๊อปอัป
  • ซ่อนองค์ประกอบโดยนำองค์ประกอบป๊อปอัปออกจาก 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 โดยมีการตัดทอนระดับบน นอกจากนี้ คุณยังดูได้ด้วยว่าองค์ประกอบใดอยู่ในเลเยอร์บนสุดบ้างผ่านเครื่องมือสำหรับนักพัฒนาเว็บ ดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์บนสุดได้ที่บทความนี้

แสดง GIF ของการรองรับเลเยอร์ชั้นบนสุดของเครื่องมือสำหรับนักพัฒนาเว็บ

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

มีอะไรอีกบ้างเมื่อนำป๊อบโอเวอร์ เรามาดูตัวอย่างกันต่อ ลองดูการสาธิตนี้พร้อมเนื้อหาบางส่วนบนหน้าเว็บ

ปุ่มการทำงานแบบลอยนี้มีตำแหน่งคงที่ด้วย z-index ที่สูง

.fab {
  position: fixed;
  z-index: 99999;
}

เนื้อหาป๊อปอัปจะซ้อนอยู่ใน DOM แต่เมื่อคุณเปิดป๊อปอัป เนื้อหาก็จะได้รับการโปรโมตเหนือองค์ประกอบตำแหน่งคงที่นั้น คุณไม่จำเป็นต้องตั้งค่ารูปแบบใดๆ

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

การจัดรูปแบบป๊อปอัป

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

[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;
}

เคล็ดลับก็คือการจัดกลุ่มการเปลี่ยนและภาพเคลื่อนไหวภายใต้คิวรี่สื่อสำหรับการเคลื่อนไหว วิธีนี้จะช่วยให้คุณรักษาเวลาไว้ได้ เนื่องจากคุณไม่สามารถแชร์ค่าระหว่าง 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 เพื่อใส่ฟังก์ชันดังกล่าว

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 แล้วภาพรวมของพฤติกรรมป๊อปโอเวอร์ล่ะ จะทำอย่างไรหากคุณไม่ต้องการ "ปิดไฟ" หรือจะใช้รูปแบบเดี่ยวๆ กับกระดาษตกแต่ง

Popover API ให้คุณระบุป๊อปโอเวอร์ 3 ประเภทที่มีลักษณะการทำงานที่แตกต่างกัน

[popover=auto]/[popover]:

  • การรองรับการฝัง ซึ่งไม่ได้หมายถึงการซ้อนอยู่ใน DOM ด้วยเช่นกัน คำจำกัดความของคำว่า "ป๊อปโอเวอร์" คือ
    • เกี่ยวข้องกันตามตำแหน่ง DOM (ย่อย)
    • เกี่ยวข้องกันโดยเรียกใช้แอตทริบิวต์ในองค์ประกอบย่อย เช่น popovertoggletarget, popovershowtarget เป็นต้น
    • ที่เกี่ยวข้องโดยแอตทริบิวต์ anchor (อยู่ระหว่างการพัฒนา CSS Anchoring API)
  • ปิดไฟ
  • การเปิดจะเป็นการปิดป๊อปอัปอื่นๆ ที่ไม่ใช่ป๊อปอัประดับบน ทดลองเล่นกับการสาธิตด้านล่างที่ไฮไลต์วิธีการทำงานของการฝังด้วยป๊อปโอเวอร์บรรพบุรุษ ดูว่าการเปลี่ยนอินสแตนซ์ popoverhidetarget/popovershowtarget บางรายการเป็น popovertoggletarget จะเปลี่ยนแปลงสิ่งต่างๆ อย่างไร
  • การปิดแบบเบาๆ จะเป็นการปิดทั้งหมด แต่การปิด 1 รายการในกลุ่มจะเป็นการปิดเฉพาะรายการที่อยู่ด้านบนในกลุ่มเท่านั้น

[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

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

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

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

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

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

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

การสาธิตนี้ใช้ 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 ทำหน้าที่เป็นคอนเทนเนอร์
  • การแจ้งเตือนใหม่จะปรากฏต่อท้ายหน้าต่างที่เปิดขึ้นมาและหน้าต่างป๊อปโอเวอร์จะปรากฏขึ้น
  • คอลัมน์เหล่านี้จะถูกนำออกด้วย 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] การแสดง 1 รายการ ซ่อนรายการอื่นเนื่องจากไม่ใช่บรรพบุรุษ
  • แสดงบน 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 ที่อยู่ใต้อินพุตหลัก
  • การปิดไฟจะปิดจานสีหากไม่มีเมนูแบบเลื่อนลง
  • ผู้สมัครอีกรายสำหรับ Anchoring API

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ขอบคุณที่ "โดนระเบิด" โดย


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