מיקוד

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

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

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

בדוגמה הזו, הערך של המאפיין tabindex גרם לסדר הכרטיסיות להיות כאוטי:

בדוגמה הזו, CSS יצר הבדל בין סדר ההזזה באמצעות Tab לבין הסדר החזותי של התוכן:

ההצהרה flex-flow: row-reverse; הפכה את הסדר החזותי. בנוסף, המאפיין order של CSS הוחל על המילה השישית, This, וכתוצאה מכך המילה הזו הוזזה מבחינה ויזואלית. סדר הלחיצה על מקש Tab הוא הסדר של הקוד, שכבר לא תואם לסדר החזותי, ולכן נוצר ניתוק למשתמשי מקלדת.

הפיכת רכיבים נייחים לאינטראקטיביים

מאפייני contenteditable ו-tabindex הם מאפיינים גלובליים, ולכן אפשר להוסיף אותם לכל רכיב ולהפוך אותו לרכיב שאפשר להתמקד בו בתהליך. אפשר להתמקד ברכיבים שניתן להתמקד בהם גם באמצעות עכבר או מצביע, אם המאפיין autofocus מוגדר, או באמצעות סקריפט, למשל עם element.focus().

המאפיין tabindex

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

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

בדף הזה, לחצן השיתוף, <share-action>, הוא רכיב בהתאמה אישית. התג tabindex="0" מוסיף את הרכיב הזה שלא ניתן להתמקד בו בדרך כלל לסדר המעבר בין הכרטיסיות שמוגדר כברירת מחדל במקלדת:

<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
  <svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
    <use href="#shareIcon" />
  </svg>
  <span>Share</span>
</share-action>

יש עוד רכיב מותאם אישית בדף הזה: הניווט המקומי הוא רכיב מותאם אישית עם ערך שלילי של tabindex:

<web-navigation-drawer type="standard" tabindex="-1">

מאפיין tabindex עם ערך שלילי מאפשר להתמקד ברכיב אבל לא להשתמש במקש Tab כדי להגיע אליו. האלמנט יכול לקבל מיקוד, למשל באמצעות HTMLElement.focus(), אבל הוא לא חלק מסדר הניווט המיקוד הרציף. המוסכמה לגבי רכיבים שאפשר להתמקד בהם אבל אי אפשר להגיע אליהם באמצעות מקש Tab היא להשתמש ב-tabindex="-1". אם מוסיפים את tabindex="-1" לרכיב אינטראקטיבי, אי אפשר יותר להגיע אליו באמצעות מקש Tab.

אפשר להשתמש בשיטה element.focus() כדי להגדיר פוקוס על רכיבים שאפשר להתמקד בהם. הדפדפנים גוללים רכיבים ממוקדים כך שיוצגו. לכן, מומלץ להימנע משימוש ב-element.focus({preventScroll:true}), כי התמקדות ברכיב לא גלוי יוצרת חוויית משתמש לא טובה.

אם רוצים להריץ שאילתה על המסמך כדי לגלות לאיזה רכיב יש מיקוד, אפשר להשתמש במאפיין Document.activeElement לקריאה בלבד.

רכיבים עם tabindex ברמה 1 ומעלה נכללים ברצף נפרד של מקשי Tab. כפי שאפשר לראות ב-Codepen, המעבר בין רכיבים באמצעות Tab מתחיל ברצף נפרד, בסדר מהערך הנמוך ביותר לערך הגבוה ביותר, לפני המעבר בין הרכיבים ברצף הרגיל (ללא הגדרה של tabindex או עם הגדרה של tabindex="0") בסדר המקור:

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

המאפיין contenteditable

המאפיין contenteditable הוזכר קודם. הגדרה של contenteditable="true" בכל רכיב מאפשרת לערוך אותו, להתמקד בו והופכת אותו לחלק מסדר המעבר באמצעות מקש Tab. ההתנהגות של המיקוד דומה להגדרה tabindex="0", אבל לא זהה. ברכיבי contenteditable מקוננים אפשר להתמקד, אבל אי אפשר להשתמש במקש Tab כדי לעבור ביניהם. כדי להגדיר שניתן יהיה להעביר את המיקוד באמצעות Tab לרכיב contenteditable מוטמע, מוסיפים את התג tabindex="0", שמוסיף אותו לסדר הניווט הרציף באמצעות מקש Tab.

הוספת autofocus לרכיבים אינטראקטיביים

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

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

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

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

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

הפיכת רכיבים אינטראקטיביים ללא פעילים

יש גם מאפייני HTML שיכולים להסיר רכיבים אינטראקטיביים מרצף המעבר בין הכרטיסיות. הוספת tabindex לרכיבים שאפשר להתמקד בהם, הוספת המאפיין disabled לרכיבי טופס תומכים והוספת המאפיין הגלובלי inert למאגר, כל אלה הופכים את הרכיבים ללא ניתנים להזזה באמצעות מקש Tab. אי אפשר להשתמש במאפיינים האלה לסירוגין.

ערך tabindex שלילי

מאפיין tabindex עם ערך שלילי מאפשר להתמקד ברכיב, אבל לא להגיע אליו באמצעות מקש Tab. אין צורך להוסיף tabindex="0" לרכיב שאפשר להעביר אליו את המיקוד כברירת מחדל, כולל קישורים, לחצנים, אמצעי בקרה בטופס ורכיבים שהערך שלהם הוא contenteditable. הוספה של tabindex עם ערך שלילי מסירה רכיבים שאפשר להעביר אליהם את המיקוד בדרך כלל מהסדר של העברת המיקוד ברצף.

ערך שלילי tabindex מונע ממשתמשי מקלדת להתמקד ברכיבים אינטראקטיביים, אבל לא משבית את הרכיב. משתמשים במצביע עדיין יכולים להתמקד ברכיב. כדי להשבית רכיב, משתמשים במאפיין disabled.

מושבת

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

disabled הוא לא מאפיין גלובלי. הוא חל על <button>,‏ <input>,‏ <optgroup>,‏ <option>,‏ <select>,‏ <textarea>, על רכיבים מותאמים אישית שמשויכים לטופס ועל <fieldset>. כשהמאפיין מוגדר ב-<optgroup> או ב-<fieldset>, כל פקדי הטופס של הצאצא מושבתים, למעט התוכן של <legend> הראשון של <fieldset>.

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

מאחר שזהו מאפיין בוליאני, נוכחות המאפיין משביתה את הרכיב שאחרת היה מופעל. אי אפשר להגדיר אותו לערך false. כדי להפעיל מחדש רכיב שהושבת, צריך להסיר את המאפיין, בדרך כלל באמצעות Element.removeAttribute('disabled').

המאפיין HTMLInputElement.disabled מאפשר לבדוק אם קלט מושבת. ‫disabled הוא לא מאפיין גלובלי, ולכן הוא לא עובר בירושה מ-HTMLElement, אבל לכל ממשק רכיב תומך, כמו HTMLSelectElement,‏ HTMLTextareaElement, יש את אותה מאפיין לקריאה בלבד.

המאפיין disabled לא חל על רכיבי inert רגילים שהופכים לניתנים להתמקדות באמצעות tabindex או contenteditable, וגם לא על הרכיב <form>. כדי להשבית את הרכיבים האלה, אפשר להשתמש במאפיין הגלובלי inert.

המאפיין inert

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

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

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

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

בדיקת ההבנה

בודקים את הידע בנושא פוקוס.

אם אי אפשר להתמקד ברכיב, איך הוא מתואר?

ריק.
אפשר לנסות שוב.
אינרטי.
תשובה נכונה!
מוסתר.
אפשר לנסות שוב.

מה יהיה הערך אם לרכיב יש מאפיין disabled?

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