סגירת תיבת דו-שיח בלחיצה מחוץ לה

תכונות אינטרנט: <dialog closedby>

בתיבות דו-שיח מודאליות מודרניות יש לעיתים קרובות תמיכה ב "סגירה קלה", שמאפשרת למשתמשים לסגור תיבת דו-שיח בלחיצה על הרקע (האזור שמחוץ לתיבת הדו-שיח). המאפיין closedby מספק דרך הצהרתית להפעיל את ההתנהגות הזו בלי JavaScript בהתאמה אישית.

הטמעה

כדי להפעיל את התכונה "סגירה בלחיצה מחוץ לחלון":

  1. מוסיפים את closedby="any" לרכיב <dialog>.
  2. פותחים את תיבת הדו-שיח באמצעות dialog.showModal().

ערכי מאפיינים

  • ‫any: מאפשר סגירה בלחיצה על הרקע, "בקשות סגירה" (המקש Esc) ומנגנוני פיתוח (למשל, dialog.close()).
  • ‫closerequest: מפעיל רק "בקשות סגירה" ומנגנוני פיתוח. זוהי ברירת המחדל לתיבות דו-שיח מודאליות.
  • ‫none: רק מנגנוני מפתחים יכולים לסגור את תיבת הדו-שיח.

עיצוב הרקע

כשתיבת דו-שיח נפתחת כמודל באמצעות showModal(), הדפדפן יוצר רכיב פסאודו ::backdrop. הרקע הזה מכסה את כל אזור התצוגה ונמצא ישירות מאחורי תיבת הדו-שיח.

/* Style the backdrop to indicate the dialog is modal */
dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px); /* Optional: add blur for modern browsers */
}

דוגמה

<!-- MANDATORY: Use closedby="any" to enable light-dismiss behavior -->
<dialog id="myDialog" closedby="any" aria-labelledby="dialogTitle">
  <form method="dialog">
    <h2 id="dialogTitle">Feedback</h2>
    <p>Click outside this box or press Esc to dismiss.</p>
    <button type="submit">Close</button>
  </form>
</dialog>

<button onclick="document.getElementById('myDialog').showModal()">Open Dialog</button>

אילוצים ונגישות

  • חובה: צריך להשתמש ב-closedby="any" כדי להפעיל סגירה בלחיצה מחוץ לאלמנט באופן הצהרתי.
  • חובה: תמיד צריך לפתוח תיבות דו-שיח מודאליות באמצעות showModal(). כך אפשר לוודא שתיבת הדו-שיח נמצאת בשכבה העליונה, שהמיקוד נשאר בה ושהמקש Esc מטופל.
  • מה כן לעשות: משתמשים ב-aria-labelledby או ב-aria-label כדי לספק תווית נגישות לתיבת הדו-שיח.
  • מה לא לעשות: להשתמש ב-closedby לתיבות דו-שיח לא מודאליות (שנפתחות באמצעות show()), כי אין להן רקע והן לא יפעילו סגירה בלחיצה מחוץ לתיבה.
  • מה לא לעשות: אל תשתמשו באירוע click ללוגיקה קריטית שצריכה לקרות לפני הסגירה. במקום זאת, האזינו לאירועים close או cancel.

אסטרטגיות חלופיות

חובה: בדפדפנים שעדיין לא תומכים ב-closedby, צריך להטמיע חלופה לסגירה בלחיצה מחוץ לתיבת הדו-שיח. כדי לעשות את זה, צריך לבדוק אם התרחש קליק מחוץ לגבולות התוכן של תיבת הדו-שיח באמצעות הסקריפט הבא:

const dialog = document.querySelector('dialog');

// Fallback for browsers without closedby support
if (!('closedBy' in HTMLDialogElement.prototype)) {
  dialog.addEventListener('click', (event) => {
    // 1. When clicking the backdrop, the event target is the dialog element itself.
    // Ignore clicks where the target is a child element inside the dialog.
    if (event.target !== dialog) return;

    // 2. Check if the click coordinates fall within the dialog's content box.
    // This distinguishes between a click on the backdrop vs a click on the dialog's background/padding.
    const rect = dialog.getBoundingClientRect();
    const isDialogContent = (
      rect.top <= event.clientY &&
      event.clientY <= rect.top + rect.height &&
      rect.left <= event.clientX &&
      event.clientX <= rect.left + rect.width
    );

    if (isDialogContent) return;

    // 3. Since the click was outside the content area (on the backdrop), manually close the dialog.
    dialog.close();
  });
}