שינוי סדר ה-DOM באמצעות tabindex

Dave Gash
Dave Gash
Meggin Kearney
Meggin Kearney
Alexandra Klepper
Alexandra Klepper

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

תמיכה בדפדפן

  • 1
  • 12
  • 1.5
  • לא יותר מ-4

מקור

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

tabindex="0": הוספת רכיב לסדר הכרטיסיות הטבעיות. אפשר למקד את האלמנט על ידי הקשה על Tab, ואפשר למקד את האלמנט על ידי קריאה ל-method focus() שלו.

tabindex="-1": הסרת רכיב מסדר הכרטיסיות הטבעיות, אבל עדיין אפשר להתמקד ברכיב באמצעות קריאה ל-method focus() שלו.

tabindex="5": כל מאפיין tabindex שגדול מ-0 מעביר את הרכיב הזה לחזית סדר הכרטיסיות הטבעיות. אם יש מספר רכיבים עם tabindex שגדול מ-0, סדר הכרטיסיות מתחיל מהערך הנמוך ביותר שגדול מאפס וממשיך למעלה. שימוש באינדקס טאבים גדול מ-0 נחשב לאנטי-דפוס.

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

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

ניהול המיקוד ברמת הדף

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

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

ניהול המיקוד ברכיבים

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

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

לפעמים קשה לדעת אילו התנהגויות של המקלדת להטמיע. במדריך Accessible Rich Internet Applications (ARIA) יש שיטות לאימות מפורטות סוגי הרכיבים והסוגים של פעולות המקלדת שהם תומכים בהם.

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

<radio-group>
    <radio-button>Water</radio-button>
    <radio-button>Coffee</radio-button>
    <radio-button>Tea</radio-button>
    <radio-button>Cola</radio-button>
    <radio-button>Ginger Ale</radio-button>
</radio-group>

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

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

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

<radio-group>
  <radio-button tabindex="0">Water</radio-button>
  <radio-button tabindex="-1">Coffee</radio-button>
  <radio-button tabindex="-1">Tea</radio-button>
  <radio-button tabindex="-1">Cola</radio-button>
  <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

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

<radio-group>
    <!-- Assuming the user pressed the down arrow, we'll focus the next available child -->
    <radio-button tabindex="-1">Water</radio-button>
    <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
    <radio-button tabindex="-1">Tea</radio-button>
    <radio-button tabindex="-1">Cola</radio-button>
    <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

כשהמשתמש מגיע לילד או לילדה האחרון (או הראשון, בהתאם לכיוון שאליו הם מעבירים את המיקוד), המיקוד עובר חזרה לילד הראשון (או האחרון).

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

מודים מלכודות למקלדת

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

סעיף 2.1.2 של WCAG קובע שאסור לנעול או לקלוט את המיקוד של המקלדת ברכיב דף מסוים. למשתמש צריכה להיות אפשרות לנווט לכל רכיבי הדף וממנו רק באמצעות המקלדת.

היוצא מן הכלל לכלל הזה הוא מודלים. עם זאת, עדיין צריך להימנע משימוש ב-tabindex כשיוצרים חלון עזר. באמצעות inert תוכלו לוודא שהמשתמשים לא יוכלו לבצע בטעות אינטראקציה עם אלמנט (מלכודת מקלדת מכוונת). משתמשים ברכיב <dialog>, שהוא קבוע כברירת מחדל, כדי ליצור מודל למשתמשים שיחסום קליקים וכרטיסיות מחוץ לחלון העזר. כך המשתמש יכול להתמקד בבחירה הנדרשת.