แสดงเคล็ดลับเครื่องมือเมื่อวางเมาส์เหนือ

ฟีเจอร์บนเว็บ: Interest invokers Popover popover="hint" Anchor positioning

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

กำลังสร้างเคล็ดลับเครื่องมือ

คุณสามารถสร้างป๊อปโอเวอร์ที่มีลักษณะการทำงานที่จำเป็นได้โดยเพิ่มแอตทริบิวต์ popover="hint" ลงใน <div> หรือองค์ประกอบอื่นๆ ที่เหมาะสมตามความหมาย เมื่อผู้ใช้เปิดเคล็ดลับเครื่องมือ ระบบจะซ่อนเคล็ดลับเครื่องมือ popover="hint" อื่นๆ แต่จะไม่ซ่อนเคล็ดลับเครื่องมือ auto หรือ manual นอกจากนี้ยังจัดการการปิดเคล็ดลับเครื่องมือที่ซ้อนกันด้วย

นอกจากนี้ยังมีลักษณะการทำงานแบบปิดเมื่อคลิกนอกองค์ประกอบ ดังนั้นเมื่อผู้ใช้คลิกหรือโฟกัสนอกป๊อปโอเวอร์ ป๊อปโอเวอร์จะปิดลง

องค์ประกอบเคล็ดลับเครื่องมือต้องมีแอตทริบิวต์ id ที่มีค่าที่ไม่ซ้ำกัน ดังนี้

<!-- MANDATORY: The tooltip container `<div>` must have a `popover` attribute.
     the value of `"hint"` ensures it can be "light dismissed". -->
<div popover="hint" id="tooltip">Tooltip content</div>

ผู้ใช้แสดงความสนใจในข้อมูลเพิ่มเติมโดยวางเมาส์เหนือหรือโฟกัสที่องค์ประกอบ <a> หรือ <button> องค์ประกอบต้องมีแอตทริบิวต์ interestfor ที่ตรงกับแอตทริบิวต์ id ของเคล็ดลับเครื่องมือ

<!-- The `interestfor` attribute can be applied to a `<button>` element: -->
<button interestfor="tooltip">Tooltip trigger</button>

<!-- The `interestfor` attribute can also be applied to an `<a>` element: -->
<a interestfor="tooltip" href="">Tooltip trigger</a>

ทริกเกอร์ต้องมีตัวบ่งชี้แบบภาพเพื่อระบุว่ามีข้อมูลเพิ่มเติมที่พร้อมใช้งานโดยการโต้ตอบกับทริกเกอร์

การช่วยเหลือพิเศษในตัวสำหรับ interestfor

เมื่อใช้ interestfor เบราว์เซอร์จะจัดการการเชื่อมต่อเทคโนโลยีความช่วยเหลือพิเศษให้คุณ ดังนี้

  • ความหมายโดยนัย: เป้าหมายที่มี popover="hint" จะได้รับบทบาทขั้นต่ำโดยนัยเป็น tooltip อย่าตั้งค่า role="tooltip" ด้วยตนเอง
  • การเชื่อมโยงโดยนัย: เบราว์เซอร์จะเชื่อมโยงองค์ประกอบต้นทางกับเป้าหมายโดยนัยผ่าน aria-describedby เมื่อเป้าหมายเป็นข้อความธรรมดา หรือผ่าน aria-details เมื่อเป้าหมายมีเนื้อหาแบบอินเทอร์แอกทีฟ อย่าเพิ่ม aria-describedby หรือ aria-details ลงในทริกเกอร์
  • เนื้อหาแบบอินเทอร์แอกทีฟ: เนื่องจากสมาคมจะเปลี่ยนไปใช้ aria-details เมื่อจำเป็น เป้าหมายจึงได้รับอนุญาตให้มีเนื้อหาแบบอินเทอร์แอกทีฟ (เช่น ลิงก์ภายใน "การ์ดความสนใจ")

ข้อจำกัดด้านการช่วยเหลือพิเศษ (WCAG 1.4.13)

แม้ว่า interestfor จะจัดการความหมายข้างต้นแล้ว แต่การติดตั้งใช้งานของคุณยังคงต้องเป็นไปตาม WCAG 1.4.13 (เนื้อหาเมื่อวางเมาส์เหนือหรือโฟกัส) ดังนี้

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

การจัดตำแหน่งเคล็ดลับเครื่องมือ

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

ในเบราว์เซอร์ที่ทันสมัยซึ่งรองรับการกำหนดตำแหน่ง Anchor แบบเนทีฟ คุณไม่จำเป็นต้องกำหนด anchor-name ในทริกเกอร์หรือ position-anchor ในเคล็ดลับเครื่องมือ คุณสามารถจัดตำแหน่งเคล็ดลับเครื่องมือให้สัมพันธ์กับ Anchor โดยนัยได้โดยตรงโดยใช้ position-area และจัดการการพลิกการชนกันด้วย position-try-fallbacks ดังนี้

[popover] {
  /* Implicit anchor from interestfor: no anchor-name or position-anchor needed */
  position-area: top;
  position-try-fallbacks: flip-block;
  margin: unset;
}

กลยุทธ์สำรอง

การสำรองและการรองรับเบราว์เซอร์สำหรับ Interest Invoker

Interest Invoker ต้องใช้ Polyfill แบบมีเงื่อนไขโดยใช้แพ็กเกจ Polyfill interestfor จาก NPM แนะนำให้รวม Polyfill แทนการใช้ CDN

บังคับ: ตรวจหาฟีเจอร์โดยตรวจสอบพร็อพเพอร์ตี้ interestForElement ใน HTMLButtonElement.prototype และโหลด Polyfill เฉพาะเมื่อไม่มีการรองรับแบบเนทีฟ

<script type="module">
  if (!HTMLButtonElement.prototype.hasOwnProperty("interestForElement")) {
    // CDN link only used for example, prefer bundling.
    await import("https://unpkg.com/interestfor@latest");
  }
</script>

ข้อควรระวังเกี่ยวกับ CSS Polyfill

เมื่อใช้ Polyfill, CSS API จะเปลี่ยนแปลงเล็กน้อยเพื่อรองรับการขาดการสนับสนุนคลาสเทียมและพร็อพเพอร์ตี้แบบเนทีฟ

  • Pseudo-class: Polyfill ไม่สามารถกำหนด Pseudo-class :interest-source และ :interest-target จริงได้ จึงใช้คลาส .interest-source และ .interest-target แทน บังคับ: รวมเข้ากับ :is() เพื่อรองรับทั้งสถานะเนทีฟและ Polyfill
/* Styles to apply when the effect is being previewed */
:is(:interest-source, .interest-source) { /* ... */ }
:is(:interest-target, .interest-target) { /* ... */ }
  • พร็อพเพอร์ตี้ CSS: สำหรับ interest-delay, interest-delay-start และ interest-delay-end Polyfill ต้องใช้ตัวแปร CSS เนื่องจากไม่สามารถอ่านคุณสมบัติที่กำหนดเองได้โดยตรงในเบราว์เซอร์ทั้งหมด
/* Adjust the start and end delay for interest invokers */
[interestfor] {
  --interest-delay-start: 0.2s;
  interest-delay-start: var(--interest-delay-start);
  --interest-delay-end: 0.1s;
  interest-delay-end: var(--interest-delay-end);
}

การรองรับเบราว์เซอร์และทางเลือกสำรองสำหรับ Popover

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

Polyfill: หากต้องการรองรับแอตทริบิวต์ popover ในเบราว์เซอร์รุ่นเก่า ให้โหลด @oddbird/popover-polyfill แบบมีเงื่อนไข จำเป็น: ตรวจหาฟีเจอร์โดยการตรวจสอบพร็อพเพอร์ตี้ popover ใน HTMLElement.prototype และโหลด Polyfill เฉพาะเมื่อไม่มีการรองรับแบบเนทีฟ อย่าโหลดโดยไม่มีเงื่อนไข

เมื่อใช้ Bundler หรือแผนที่การนำเข้า ให้ทำดังนี้

// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
  import("@oddbird/popover-polyfill");
}

หากไม่มี Bundler ให้นำเข้าจาก CDN ภายใน <script type="module">:

<script type="module">
  if (!("popover" in HTMLElement.prototype)) {
    import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
  }
</script>

ข้อควรระวังเกี่ยวกับรูปแบบ: Polyfill ไม่สามารถกำหนดคลาสจำลอง :popover-open จริงได้ จึงใช้คลาส .\:popover-open แทน จำเป็น: รวมทั้ง 2 รายการเข้าด้วยกันโดยใช้ :is() หรือ :where() ไม่เช่นนั้นเบราว์เซอร์ที่ไม่มี :popover-open จะทิ้งกฎทั้งหมด

[popover]:is(:popover-open, .\:popover-open) {
  display: block;
}

หรือสำหรับทางเลือกสำรองแบบเดิมที่ไม่มี Polyfill ให้ใช้ position: fixed และคำนวณพิกัดด้วยตนเองผ่าน getBoundingClientRect() หรือใช้การกำหนดตำแหน่งเริ่มต้นด้วย inset: auto หากยอมรับได้สำหรับกรณีการใช้งาน

popover-polyfill ไม่ได้ใช้ Polyfill กับลักษณะการทำงานของคำแนะนำในเบราว์เซอร์ที่รองรับ popover แต่ไม่รองรับ popover="hint" สำหรับเบราว์เซอร์เหล่านั้น เคล็ดลับเครื่องมือที่เปิดผ่านการโฟกัสอาจยังคงเปิดอยู่เมื่อเคล็ดลับเครื่องมือที่ 2 เปิดผ่านการวางเมาส์เหนือ

หากต้องการรองรับเบราว์เซอร์ที่ไม่มีการกำหนดตำแหน่ง Anchor คุณสามารถใช้ Polyfill @oddbird/css-anchor-positioning ได้ หรือจะใช้ @supports เพื่อระบุตำแหน่งสำรองก็ได้

เมื่อใช้ Polyfill @oddbird/css-anchor-positioning สำหรับการรองรับเบราว์เซอร์เดิม โปรดทราบว่า Polyfill ไม่รองรับ Anchor โดยนัยหรือ position-area ในป๊อปโอเวอร์ ตั้งค่า anchor-name อย่างชัดเจนในทริกเกอร์ ตั้งค่า position-anchor ในป๊อปโอเวอร์ และจัดตำแหน่งโดยใช้ฟังก์ชันแทรก anchor() แทน position-area ดังนี้

<!-- MANDATORY: Conditionally install the anchor positioning polyfill -->
<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    await import("https://unpkg.com/@oddbird/css-anchor-positioning");
  }
</script>
button[interestfor="tooltip-attrs"] {
  /* MANDATORY: Each trigger and popover pair must have a unique anchor name, referenced by `anchor-name` on the trigger and `position-anchor` on the popover. */
  anchor-name: --tooltip-attrs;
}
#tooltip-attrs {
  position-anchor: --tooltip-attrs;
  /* If using the anchor positioning polyfill with a popover, DO use `anchor()` functions, and not `position-area. */
  top: anchor(bottom);
  left: anchor(right);
  margin: unset;
}