Dialog

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

תיבות הדו-שיח יכולות להיות מודולריות (אפשר לתקשר רק עם התוכן בתיבת הדו-שיח) או לא מודאליות (עדיין אפשר ליצור אינטראקציה עם תוכן מחוץ לתיבת הדו-שיח). תיבות דו-שיח מודולריות מוצגות בחלק העליון של שאר תוכן הדף. שאר הדף הוא inert, וכברירת מחדל, הוא מוסתר על ידי רקע שקוף למחצה.

רכיב ה-HTML הסמנטי <dialog> ליצירת תיבת דו-שיח כולל סמנטיקה, אינטראקציות עם המקלדת וכל המאפיינים והשיטות של ממשק HTMLDialogElement.

כאן מוצגת דוגמה של מודול <dialog>. פותחים את תיבת הדו-שיח באמצעות הלחצן 'פתיחת תיבת דו-שיח מודאלית'. אחרי שפותחים את תיבת הדו-שיח אפשר לסגור אותה בשלוש דרכים: מקש Escape, שליחת טופס עם לחצן עם ההגדרה formmethod="dialog" (או אם הטופס עצמו מוגדר method="dialog") והשיטה HTMLDialogElement.close().

לHTMLDialogElement יש שלוש שיטות עיקריות, וכל השיטות שעברו בירושה מ-HTMLElement.

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

הקובץ <dialog> נפתח באמצעות method HTMLDialogElement.showModal(), לכן זוהי תיבת דו-שיח של מודל. פתיחת תיבת דו-שיח בחלון מודאלי משביתה ומסתירה את כל התוכן מלבד תיבת הדו-שיח עצמה. אם תעבירו את העכבר מעל ממשק המשתמש מחוץ לתיבת הדו-שיח, תוכלו לראות שכל הרכיבים מתנהגים כאילו מוגדר הערך pointer-events: none;, גם הלחצן שפותח את תיבת הדו-שיח לא מגיב לאינטראקציות.

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

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

יש מאפיין גלובלי inert שאפשר להשתמש בו כדי להשבית רכיב ואת כל הצאצאים שלו, מלבד כל תיבת דו-שיח פעילה. כשפותחים תיבת דו-שיח מודאלית באמצעות showModal(), ההתמדה או ההשבתה מוצעות בחינם. המאפיין לא מוגדר באופן מפורש.

אפשר לעצב את הרקע שמסתיר את כל התוכן מלבד תיבת הדו-שיח באמצעות פסאודו-רכיב ::backdrop. הרקע מוצג רק כאשר <dialog> מוצג עם השיטה .showModal(). פסאודו-הרכיב הזה תואם לכל תמונות הרקע, כולל זו שמוצגת כשנעשה שימוש ב-FullScreen API. למשל, כשצופים בסרטון במצב מסך מלא שיחס הגובה-רוחב שלו שונה מיחס הגובה-רוחב של המסך או הצג.

תיבות דו-שיח שאינן מודליות

גם HTMLDialogElement.show() פותח תיבת דו-שיח, אבל בלי להוסיף רקע ובלי לגרום לפעילות לא יציבה. מקש Escape לא סוגר תיבות דו-שיח שאינן מודליות. לכן חשוב יותר להקפיד לכלול שיטה לסגירת תיבת הדו-שיח שאינה חלון מודאלי. כך, אם המיקום קרוב יותר מחוץ לתיבת הדו-שיח, חשוב להבין שהמיקוד עובר לרכיב שפתח את תיבת הדו-שיח, ויכול להיות שחוויית המשתמש לא תהיה הטובה ביותר.

לחצן לסגירת תיבת הדו-שיח לא נדרש באופן רשמי על ידי המפרט, אבל אפשר לראות אותו כנדרש. מקש Escape סוגר תיבת דו-שיח ראשית, אבל לא תיבת דו-שיח שאינה חלון מודאלי. לחצן גלוי שאפשר לקבל עליו מיקוד משפר את הנגישות ואת חוויית המשתמש.

סגירת תיבת דו-שיח

אין צורך בשיטה HTMLDialogElement.close() כדי לסגור תיבת דו-שיח. אין צורך ב-JavaScript בכלל. כדי לסגור את <dialog> בלי JavaScript, צריך לכלול טופס עם שיטת של תיבת דו-שיח. לשם כך צריך להגדיר את method="dialog" ב-<form> או ב-formmethod="dialog" בלחצן.

כשמשתמש שולח באמצעות השיטה dialog, המצב של הנתונים שהוזנו על ידי המשתמש נשמר. כשיש אירוע שליחה – הטופס עובר אימות אילוצים (אלא אם מגדירים את novalidate) – נתוני המשתמש לא נמחקים ולא נשלחים. ניתן לכתוב לחצן סגירה ללא JavaScript כך:

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

ייתכן שבדוגמה הזו הבחנתם במאפיין autofocus שהוגדר בסגירה של <button>. רכיבים עם המאפיין autofocus שהוגדר בתוך <dialog> לא יתמקדו בטעינת הדף (אלא אם הדף נטען ותיבת הדו-שיח גלויה). עם זאת, המיקוד שלהן יהיה כשתיבת הדו-שיח תיפתח.

כברירת מחדל, כשפותחים תיבת דו-שיח, המיקוד יהיה על הרכיב הראשון שניתן להתמקד בו בתיבת הדו-שיח, אלא אם כן לרכיב אחר בתיבת הדו-שיח מוגדר מאפיין autofocus. הגדרת המאפיין autofocus בלחצן הסגירה מבטיחה שהוא יקבל מיקוד כשתיבת הדו-שיח נפתחת. אבל כדי לכלול autofocus בתוך <dialog> צריך לקחת בחשבון הרבה שיקולים. כל הרכיבים ברצף שלפני הדילוג על רכיב המיקוד האוטומטי. מידע נוסף על המאפיין הזה מופיע בשיעור שמתמקד.

הממשק HTMLDialogElement כולל מאפיין returnValue. כששולחים טופס עם method="dialog", הפרמטר returnValue מוגדר לערך name, אם קיים, של לחצן השליחה שמשמש לשליחת הטופס. אם נכתוב <button type="submit" name="toasty">close</button>, הערך של returnValue יהיה toasty.

כשפותחים תיבת דו-שיח, מופיע המאפיין open הבוליאני, כלומר תיבת הדו-שיח פעילה ואפשר ליצור איתה אינטראקציה. כשפותחים תיבת דו-שיח על ידי הוספת המאפיין open במקום דרך .show() או .showModal(), תיבת הדו-שיח לא תהיה מודאלית. המאפיין HTMLDialogElement.open יחזיר את הערך true או false, בהתאם לסוג תיבת הדו-שיח שזמין לאינטראקציה – לא אם הוא חלון מודאלי או לא.

השימוש ב-JavaScript הוא השיטה המועדפת לפתיחת תיבת דו-שיח, כולל הוספת המאפיין open בזמן טעינת הדף והסרת אותו באמצעות .close(). לעומת זאת, תיבת הדו-שיח תהיה זמינה גם כש-JavaScript לא זמין.

פרטים נוספים

אין להשתמש ב-tabindex

הרכיב שמופעל כדי לפתוח את תיבת הדו-שיח ולחצן הסגירה שכלול בה (ואולי גם תוכן אחר) יכולים לקבל מיקוד והם יכולים להיות אינטראקטיביים. הרכיב <dialog> אינו אינטראקטיבי ואין לו מיקוד. אין להוסיף את המאפיין tabindex לתיבת הדו-שיח עצמה.

תפקידים ב-ARIA

התפקיד המשתמע הוא dialog. אם תיבת הדו-שיח היא חלון אישור שבו מוצגת הודעה חשובה שדורשת אישור או תגובה אחרת מהמשתמש, מגדירים את role="alertdialog". תיבת הדו-שיח צריכה גם להיות בעלת שם נגיש. אם ניתן לספק שם נגיש לטקסט, מוסיפים aria-labelledby="idOfLabelingText".

ברירות מחדל של שירות CSS

לתשומת ליבך, דפדפנים מספקים עיצוב ברירת מחדל עבור dialog. Firefox, Chrome ו-Edge מוגדרים color: CanvasText; background-color: Canvas; ו-Safari מגדיר את color: black; background-color: white; בגיליונות הסגנונות של הסוכנים שלהם. הערך color עובר בירושה מ-dialog ולא מ-body או מ-:root, וזה עשוי להיות בלתי צפוי. הנכס background-color לא עובר בירושה.

בדיקת ההבנה

בחינת הידע שלכם בנושא רכיב תיבת הדו-שיח.

איך מעצבים את האזור שמאחורי תיבת הדו-שיח?

עם פסאודו-רכיב ::background.
אפשר לנסות שוב.
עם פסאודו-רכיב ::backdrop.
נכון!
עם הנכס background.
אפשר לנסות שוב.