התמקדות בסגנון

Rob Dodson
Rob Dodson

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

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

להשתמש ב-:focus כדי להציג תמיד אינדיקטור מיקוד

פסאודו-הקלאס :focus מיושם בכל פעם שרכיב מקבל את המיקוד, ללא קשר למכשיר הקלט (עכבר, מקלדת, סטיילוס וכו') או לשיטה שבה משתמשים כדי להעביר אליו את המיקוד. לדוגמה, ל-<div> שבהמשך יש tabindex שמאפשר להתמקד בו. יש לו גם סגנון מותאם אישית למצב :focus:

div[tabindex="0"]:focus {
  outline: 4px dashed orange;
}

לא משנה אם תלחצו עליו בעכבר או תעבירו אליו את הסמן במקלדת, <div> תמיד ייראה אותו דבר.

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

לדוגמה, ל-<button> שבהמשך יש גם סגנון מותאם אישית למצב :focus שלה.

button:focus {
  outline: 4px dashed orange;
}

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

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

שימוש ב-:focus-visible כדי להציג אינדיקטור מיקוד באופן סלקטיבי

הסיווג המזויף החדש :focus-visible חל בכל פעם שרכיב מקבל את המיקוד והדפדפן קובע באמצעות שיטות ניתוח נתונים (heuristics) שיציג אינדיקטור של מיקוד יהיה מועיל למשתמש. באופן ספציפי, אם האינטראקציה האחרונה של המשתמש הייתה באמצעות המקלדת והלחיצה על המקש לא כללה מקש meta,‏ ALT / OPTION או CONTROL, אז :focus-visible יתאים.

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

button:focus-visible {
  outline: 4px dashed orange;
}

שימוש ב-:focus-within כדי לעצב את הרכיב ההורה של אלמנט שהתמקדתם בו

פסאודו-הקלאס :focus-within מופעל על רכיב כאשר המשתמש מתמקד ברכיב עצמו או כאשר המשתמש מתמקד ברכיב אחר בתוך אותו רכיב.

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

form:focus-within {
  background: #ffecb3;
}

מתי להציג אינדיקטור של התמקדות

כלל טוב הוא לשאול את עצמכם: "אם תלחצו על הלחצן הזה במכשיר נייד, האם תצפו להופעת מקלדת?"

אם התשובה היא 'כן', סביר להניח שתמיד צריך להציג ברכיב הבקרה אינדיקטור של מיקוד, ללא קשר להתקן הקלט שמשמש למיקוד שלו. דוגמה טובה לכך היא הרכיב <input type="text">. המשתמש יצטרך לשלוח קלט לרכיב באמצעות המקלדת, ללא קשר לאופן שבו רכיב הקלט קיבל את המיקוד במקור. לכן, מומלץ להציג תמיד אינדיקטור של מיקוד.

אם התשובה היא 'לא', יכול להיות שהפקד יציג אינדיקטור של מיקוד באופן סלקטיבי. דוגמה טובה לכך היא הרכיב <button>. אם משתמש לוחץ עליו בעכבר או במסך מגע, הפעולה תושלם וייתכן שלא יהיה צורך במדד המיקוד. עם זאת, אם המשתמש מנווט באמצעות מקלדת, כדאי להציג אינדיקטור של המיקוד כדי שהמשתמש יוכל להחליט אם ללחוץ על הלחצן באמצעות המקשים ENTER או SPACE.

יש להימנע מ-outline: none

האמת היא שהדרך שבה דפדפנים מחליטים מתי לצייר אינדיקטור למיקוד מבלבלת מאוד. שינוי המראה של אלמנט <button> באמצעות CSS או הוספת tabindex לאלמנט יגרום להפעלה של התנהגות ברירת המחדל של טבעת המיקוד בדפדפן.

דפוס נפוץ מאוד של שימוש לא נכון הוא הסרת אינדיקטור המיקוד באמצעות CSS, למשל:

/* Don't do this!!! */
:focus {
  outline: none;
}

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

/*
  This will hide the focus indicator if the element receives focus via the
  mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
  outline: none;
}

/*
  Optionally: Define a strong focus indicator for keyboard focus.
  If you choose to skip this step, then the browser's default focus
  indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
  
}