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

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

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

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

เมื่อสร้างหน้าต่างป๊อปโอเวอร์มักจะมีข้อกังวลที่สำคัญ 2 ประการ ได้แก่

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

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

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

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

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

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

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

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

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

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

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

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

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

Dialog.showModal();

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

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

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

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


ก่อนที่จะดูกรณีการใช้งานทั่วไปและตัวอย่าง


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

เราได้กล่าวถึงลักษณะการทำงานของการโต้ตอบที่ไม่ใช้ JavaScript แล้ว แล้วถ้าเป็นลักษณะการทำงานโดยรวมของหน้าต่างป๊อปโอเวอร์ ฉันต้องทำอย่างไรหากไม่ต้องการ "ปิดไฟ" หรือต้องการใช้รูปแบบซิงเกิลตันกับป๊อปโอเวอร์

API ของ Popover ช่วยให้คุณระบุป๊อปอัปได้ 3 ประเภทซึ่งมีลักษณะการทำงานที่แตกต่างกัน

[popover=auto]/[popover]:

  • การรองรับ Nesting ซึ่งไม่ได้หมายถึงมีการฝังใน 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

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

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

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

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

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

แต่เราอยากให้คุณกำหนดประเด็นนี้ได้ด้วยสไตล์ของคุณ เรามี API ที่ใช้ร่วมกันที่อยู่ระหว่างการพัฒนาควบคู่ไปกับ Popover API เพื่อรับมือกับปัญหานี้ API "การกำหนดตำแหน่ง Anchor ของ 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 ทำหน้าที่เป็นคอนเทนเนอร์
  • การแจ้งเตือนใหม่จะต่อท้ายป๊อปอัปและป๊อปอัปจะปรากฏ
  • ข้อมูลเหล่านี้จะถูกนำออกด้วย 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 เพียง 1 รายการ

  • ใช้ JavaScript เพื่อรักษารายการป๊อปอัปที่มองเห็นได้
  • ใช้ชื่อคลาสกับป๊อปอัปที่ต่ำที่สุดในเลเยอร์บนสุด

ป๊อปอัปเคอร์เซอร์ที่กำหนดเอง

การสาธิตนี้แสดงวิธีใช้ popover เพื่อโปรโมต canvas ที่เลเยอร์บนสุด และใช้เพื่อแสดงเคอร์เซอร์ที่กำหนดเอง

  • โปรโมต canvas ไปยังเลเยอร์บนสุดด้วย showPopover และ [popover=manual]
  • เมื่อเปิดป๊อปโอเวอร์อื่นๆ ให้ซ่อนและแสดงป๊อปอัป canvas เพื่อให้แน่ใจว่าจะปรากฏที่ด้านบน

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

การสาธิตนี้แสดงวิธีใช้ป๊อปอัปเป็นไฟล์ดำเนินการ

  • ให้ป๊อปอัปแสดงโดยค่าเริ่มต้นโดยลบล้าง display
  • Actionsheet เปิดอยู่ด้วยทริกเกอร์ป๊อปโอเวอร์
  • เมื่อมีการแสดงป๊อบโอเวอร์ จะเป็นการเลื่อนชั้นที่อยู่บนสุดและแปลไปสู่มุมมอง
  • การปิดแสงอาจใช้เพื่อส่งคืนได้

เปิดใช้งานป๊อปอัปของแป้นพิมพ์

การสาธิตนี้แสดงให้เห็นวิธีใช้หน้าต่างป็อปโอเวอร์สำหรับ UI ของรูปแบบชุดคำสั่ง

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

ป๊อบโอเวอร์ตามลำดับเวลา

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

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

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

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

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

ปุ่มติดตาม

การสาธิตนี้แสดงวิธีทำให้ป๊อปอัปทำตามเครื่องหมาย Caret อินพุตได้

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

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

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

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

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

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

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

ขอขอบคุณที่ "เข้ามา"


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