דו שיח

רכיב הדיאלוג הוא רכיב שימושי לייצוג כל סוג של דיאלוג ב-HTML. כאן מוסבר איך הוא פועל.

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

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

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

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

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

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

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

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

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

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

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

לא צריך להשתמש בשיטה HTMLDialogElement.close() כדי לסגור תיבת דו-שיח. לא צריך JavaScript בכלל. כדי לסגור את <dialog> בלי JavaScript, צריך לכלול טופס עם שיטת dialog, על ידי הגדרת 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.
אפשר לנסות שוב.