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

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

אם סמן המיקוד שמוגדר כברירת מחדל בדפדפן לא מתאים לעיצוב שלכם, תוכלו להשתמש ב-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 {
  …
}