במדריך הזה מוסבר איך ליצור תפריט ניווט ראשי נגיש באתר. אתם לומדים על HTML סמנטי, נגישות ואיך השימוש במאפייני ARIA יכול לפעמים להזיק יותר מאשר להועיל.
יש הרבה דרכים שונות לבנות את הניווט הראשי של אתר, מבחינת הסגנון, הפונקציונליות, תגי העיצוב והמידע הסמנטי. אם ההטמעה מינימליסטית מדי, היא תתאים לרוב האנשים, אבל חוויית המשתמש (UX) לא תהיה טובה. אם הוא מורכב מדי, הוא עלול לבלבל את המשתמשים או אפילו למנוע מהם לגשת אליו בכלל.
ברוב האתרים, כדאי ליצור משהו שהוא לא פשוט מדי ולא מסובך מדי.
בנייה שכבה אחר שכבה
במדריך הזה תתחילו עם הגדרה בסיסית ותוסיפו תכונות שכבה אחר שכבה, עד שתספקו מספיק מידע, סגנון ופונקציונליות כדי לרצות את רוב המשתמשים. כדי לעשות את זה, אתם משתמשים בעיקרון של שיפור הדרגתי (progressive enhancement), שקובע שמתחילים עם הפתרון הכי בסיסי ויציב, ומוסיפים בהדרגה שכבות של פונקציונליות. אם שכבה אחת לא פועלת מסיבה כלשהי, הניווט עדיין יפעל כי הוא חוזר בצורה חלקה לשכבה שמתחתיה.
מבנה בסיסי
כדי ליצור ניווט בסיסי, צריך שני דברים: רכיבי <a> וכמה שורות של CSS כדי לשפר את העיצוב והפריסה שמוגדרים כברירת מחדל לקישורים.
HTML
<a href="/home">Home</a> <a href="/about-us">About us</a> <a href="/pricing">Pricing</a> <a href="/contact">Contact</a>CSS
/* Define variables for your colors */ :root { --color-shades-dark: rgb(25, 25, 25); } /* Use the alternative box model Details: <https://web.dev/learn/css/box-model/> */ *{ box-sizing: border-box; } /* Basic font styling */ body { font-family: Segoe UI, system-ui, -apple-system, sans-serif; font-size: 1.6rem; } /* Link styling */ a { --text-color: var(--color-shades-dark); border-block-end: 3px solid var(--border-color, transparent); color: var(--text-color); display: inline-block; margin-block-end: 0.5rem; /* See note at the bottom of this chapter */ margin-inline-end: 0.5rem; padding: 0.1rem; text-decoration: none; } /* Change the border-color on :hover and :focus */ a:where(:hover, :focus) { --border-color: var(--text-color); }
השיטה הזו מתאימה לרוב המשתמשים, לא משנה איך הם נכנסים לאתר. אפשר לנווט באמצעות עכבר, מקלדת, מכשיר עם מסך מגע או קורא מסך, אבל יש מקום לשיפור. כדי לשפר את חוויית המשתמש, אפשר להרחיב את התבנית הבסיסית הזו ולהוסיף לה עוד פונקציונליות ומידע.
אתם יכולים לבצע את הפעולות הבאות:
- הדגשת הדף הפעיל.
- הקראת מספר הפריטים למשתמשים של קורא המסך.
- מוסיפים מאפיין ARIA ומאפשרים למשתמשים בקורא מסך לגשת ישירות לניווט באמצעות קיצור דרך.
- הסתרת הניווט באזורי תצוגה צרים.
- שיפור סגנון המיקוד.
הדגשת הדף הפעיל
כדי להדגיש את הדף הפעיל, אפשר להוסיף מחלקה לקישור המתאים.
<a href="/about-us" class="active-page">About us</a>
הבעיה בגישה הזו היא שהמידע על הקישור הפעיל מועבר באופן חזותי בלבד. משתמש עיוור שנעזר בקורא מסך לא יכול להבחין בין הדף הפעיל לדפים אחרים. למרבה המזל, התקן Accessible Rich Internet Applications (ARIA) מציע דרך להעביר את המידע הזה גם באופן סמנטי. השתמשו במאפיין ובערך aria-current="page" במקום במחלקה.
aria-current (מצב) מציין את האלמנט שמייצג את הפריט הנוכחי בתוך מאגר או קבוצה של אלמנטים קשורים.
אסימון דף שמשמש לציון קישור בתוך קבוצה של קישורי עימוד, שבה הקישור מעוצב באופן חזותי כדי לייצג את הדף שמוצג כרגע.
[Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)
בעזרת המאפיין הנוסף, קורא המסך יקריא עכשיו משהו כמו "הדף הנוכחי, קישור, מידע על החברה" במקום רק "קישור, מידע על החברה".
<a href="/about-us" aria-current="page" class="active-page">About us</a>
תופעת לוואי נוחה היא שאפשר להשתמש במאפיין כדי לבחור את הקישור הפעיל ב-CSS, כך שהמחלקה active-page מיושנת.
<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
--border-color: var(--color-highlight);
--text-color: var(--color-highlight);
}
הקראת מספר הפריטים
משתמשים רואים יכולים להסתכל על הניווט ולהבין שהוא מכיל רק ארבעה קישורים. משתמש עיוור שנעזר בקורא מסך לא יכול לקבל את המידע הזה באותה מהירות. יכול להיות שהם יצטרכו לעבור על כל רשימת הקישורים. יכול להיות שזו לא תהיה בעיה אם הרשימה קצרה כמו בדוגמה הזו, אבל אם היא מכילה 40 קישורים, המשימה הזו יכולה להיות מסורבלת. אם משתמשים בקורא מסך יודעים מראש שהניווט מכיל הרבה קישורים, הם יכולים להחליט להשתמש בדרך אחרת ויעילה יותר לניווט, כמו החיפוש באתר.
דרך טובה להעביר את מספר הפריטים מראש היא לעטוף כל קישור בפריט רשימה (<li>), שמוטמע ברשימה לא מסודרת (<ul>).
<ul>
<li>
<a href="/home">Home</a>
</li>
<li>
<a href="/about-us" aria-current="page">About us</a>
</li>
<li>
<a href="/pricing">Pricing</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
כשמשתמשים בקורא מסך מגיעים לרשימה, התוכנה שלהם מכריזה משהו כמו "רשימה, 4 פריטים".
הנה הדגמה של הניווט באמצעות קורא המסך NVDA ב-Windows.
עכשיו צריך להתאים את הסגנון כדי שהאתר ייראה כמו קודם.
/* Remove the default list styling and create a flexible layout for the list */
ul {
display: flex;
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
/* Basic link styling */
a {
--text-color: var(--color-shades-dark);
border-block-end: 3px solid var(--border-color, transparent);
color: var(--text-color);
padding: 0.1rem;
text-decoration: none;
}
לשימוש ברשימות יכולים להיות יתרונות רבים למשתמשים בקוראי מסך:
- הם יכולים לקבל את המספר הכולל של הפריטים לפני שהם מבצעים פעולה כלשהי.
- הם יכולים להשתמש במקשי קיצור כדי לעבור מפריט לפריט ברשימה.
- הם יכולים להשתמש בקיצורי דרך כדי לעבור מרשימה לרשימה.
- יכול להיות שקורא המסך יכריז על האינדקס של הפריט הנוכחי (לדוגמה, "פריט ברשימה, שני מתוך ארבעה").
בנוסף, אם הדף מוצג בלי CSS, הרשימה מציגה את הקישורים כקבוצה עקבית של פריטים במקום סתם ערימה של קישורים.
פרט חשוב לגבי VoiceOver ב-Safari הוא שאתם מאבדים את כל היתרונות האלה כשאתם מגדירים את list-style: none. זה מכוון. הצוות של WebKit החליט להסיר את הסמנטיקה של הרשימה, כשהרשימה לא נראית כמו רשימה. בהתאם למורכבות של הניווט, יכול להיות שזו תהיה בעיה או שלא. מצד אחד, עדיין אפשר להשתמש בניווט והבעיה משפיעה רק על VoiceOver ב-Safari. VoiceOver עם Chrome או Firefox עדיין מקריא את מספר הפריטים, כמו גם קוראי מסך אחרים, כמו NVDA. מצד שני, המידע הסמנטי יכול להיות שימושי מאוד במצבים מסוימים. כדי להחליט, כדאי לבדוק את הניווט עם משתמשים אמיתיים של קורא מסך ולקבל מהם משוב. אם אתם רוצים ש-VoiceOver ב-Safari יתנהג כמו כל קוראי המסך האחרים, אתם יכולים לעקוף את הבעיה על ידי הגדרת תפקיד הרשימה של ARIA באופן מפורש ב-<ul>. הפעולה הזו מחזירה את ההתנהגות למצב שהיה לפני שהסרתם את סגנון הרשימה. מבחינה חזותית, הרשימה עדיין נראית אותו דבר.
<ul role="list">
<li>
<a href="/home">Home</a>
</li>
...
</ul>
הוספת ציון דרך
בלי הרבה מאמץ, שיפרתם את חוויית השימוש של משתמשים בקורא מסך, אבל יש עוד דבר אחד שאתם יכולים לעשות. מבחינה סמנטית, הניווט הוא עדיין רק רשימה של קישורים וקשה לדעת שהרשימה הספציפית הזו היא הניווט הראשי של האתר שלכם. אפשר להפוך את הרשימה הרגילה הזו לרשימת ניווט על ידי הוספת רכיב <nav> מסביב ל-<ul>.
לשימוש ברכיב <nav> יש כמה יתרונות. באופן ספציפי, קורא מסך מקריא משהו כמו "ניווט" כשהמשתמש מבצע אינטראקציה עם הרכיב, ומוסיף מאפיין ARIA לדף. ציוני דרך הם אזורים מיוחדים בדף, כמו <header>, <footer> או <main>, שקורא המסך יכול לדלג אליהם. כדאי להוסיף לדף מאפייני ARIA, כי הם מאפשרים למשתמשים בקורא מסך לגשת ישירות לאזורים חשובים בדף בלי צורך באינטראקציה עם שאר הדף. לדוגמה, אפשר לעבור מציון דרך אחד לשני על ידי לחיצה על המקש D ב-NVDA. ב-Voice Over, אפשר להשתמש ברוטור כדי להציג את כל נקודות הציון בדף על ידי לחיצה על VO + U.
ברשימה הזו מוצגים 4 ציוני דרך: באנר שהוא הרכיב <header>, ניווט שהוא הרכיב <nav>, ראשי שהוא הרכיב <main> ומידע על התוכן שהוא הרכיב <footer>. הרשימה הזו לא צריכה להיות ארוכה מדי. כדאי לסמן רק חלקים קריטיים בממשק המשתמש כנקודות ציון, כמו החיפוש באתר, ניווט מקומי או חלוקה לדפים.
אם יש לכם ניווט בכל האתר, ניווט מקומי לדף ועימוד בדף אחד, יכול להיות שיהיו לכם גם 3 רכיבי <nav>. זה בסדר, אבל עכשיו יש שלושה ציוני דרך לניווט, ומבחינה סמנטית כולם נראים אותו דבר. קשה להבדיל ביניהם, אלא אם מכירים את מבנה הדף ממש טוב.
כדי להבדיל ביניהם, צריך לתייג אותם באמצעות aria-labelledby או aria-label.
<nav aria-label="Main">
<ul>
<li>
<a href="/home">Home</a>
</li>
...
</ul>
</nav>
...
<nav aria-label="Select page">
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
אם התווית שבחרתם כבר קיימת במקום כלשהו בדף, אתם יכולים להשתמש במקום זאת ב-aria-labelledby ולהפנות לתווית הקיימת באמצעות המאפיין id.
<nav aria-labelledby="pagination_heading">
<h2 id="pagination_heading">Select a page</h2>
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
תווית תמציתית מספיקה, אין צורך להאריך במילים. השמיטו ביטויים כמו "ניווט" או "תפריט" כי קורא המסך כבר מספק למשתמשים את המידע הזה.
הסתרת הניווט באזורי תצוגה צרים
באופן אישי, אני לא אוהב להסתיר את הניווט הראשי באזורי תצוגה צרים, אבל אם רשימת הקישורים ארוכה מדי, אין ברירה. במקרה כזה, במקום הרשימה, המשתמשים רואים כפתור עם התווית "תפריט" או סמל המבורגר או שילוב של שניהם. לחיצה על הכפתור מציגה ומסתירה את הרשימה. אם אתם מכירים את היסודות של JavaScript ו-CSS, זו משימה אפשרית, אבל יש כמה דברים שצריך לטפל בהם מבחינת חוויית המשתמש והנגישות.
- צריך להסתיר את הרשימה באופן נגיש.
- הניווט חייב להיות נגיש באמצעות המקלדת.
- הניווט צריך להעביר מידע על כך שהוא גלוי או לא.
הוספת כפתור המבורגר
מכיוון שאתם פועלים לפי העיקרון של שיפור הדרגתי, אתם רוצים לוודא שהניווט עדיין פועל והגיוני גם כש-JavaScript מושבת.
הדבר הראשון שהניווט צריך הוא כפתור המבורגר. יוצרים אותו ב-HTML ברכיב תבנית, משכפלים אותו ב-JavaScript ומוסיפים אותו לסרגל הניווט.
<nav id="mainnav">
...
</nav>
<template id="burger-template">
<button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
<svg width="24" height="24" aria-hidden="true">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
</svg>
</button>
</template>
- המאפיין
aria-expandedמציין לתוכנת קורא המסך אם הרכיב שהלחצן שולט בו מורחב או לא. aria-labelנותן לכפתור תווית נגישות, חלופת טקסט לסמל ההמבורגר.- אתם מסתירים את
<svg>מהטכנולוגיה המסייעת באמצעותaria-hiddenכי כבר יש לו תווית טקסט שסופקה על ידיaria-label. - המאפיין
aria-controlsמציין לטכנולוגיה המסייעת שתומכת במאפיין (לדוגמה, JAWS) באיזה רכיב הלחצן שולט.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');
// Toggle aria-expanded attribute
button.addEventListener('click', e => {
// aria-expanded="true" signals that the menu is currently open
const isOpen = button.getAttribute('aria-expanded') === "true"
button.setAttribute('aria-expanded', !isOpen);
});
// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
if (e.code === 'Escape') {
button.setAttribute('aria-expanded', false);
}
});
// Add the button to the page
nav.insertBefore(burgerClone, list);
- למשתמשים נוח כשיש להם אפשרות לסגור את הניווט מתי שהם רוצים, למשל על ידי לחיצה על מקש Escape.
- חשוב להשתמש ב-
insertBeforeבמקום ב-appendChildכי הכפתור צריך להיות הרכיב הראשון בניווט. אם משתמש במקלדת או בקורא מסך לוחץ על Tab אחרי שהוא לוחץ על הכפתור, הוא מצפה שהמיקוד יעבור לפריט הראשון ברשימה. אם הלחצן מופיע אחרי הרשימה, זה לא המצב.
בשלב הבא, מאפסים את סגנון ברירת המחדל של הלחצן ומוודאים שהוא גלוי רק באזורי תצוגה צרים.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
}
}
/* Reset button styling */
button {
all: unset;
display: var(--nav-button-display, flex);
}
הסתרת הרשימה
לפני שמסתירים את הרשימה, ממקמים את הניווט והרשימה ומעצבים אותם כך שהפריסה תהיה מותאמת לאזורי תצוגה צרים, אבל עדיין תיראה טוב במסכים גדולים יותר.
קודם כל, מסירים את <nav> מהזרימה הטבעית של הדף וממקמים אותו בפינה העליונה של אזור התצוגה.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
}
nav {
position: var(--nav-position, fixed);
inset-block-start: 1rem;
inset-inline-end: 1rem;
}
בשלב הבא, משנים את הפריסה של אזורי תצוגה צרים על ידי הוספת מאפיין מותאם אישית חדש (—-nav-list-layout). כברירת מחדל, הפריסה היא של עמודה, והיא משתנה לשורה במסכים גדולים יותר.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
}
}
ul {
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
הניווט אמור להיראות בערך כך באזורי תצוגה צרים.
ברור שהרשימה צריכה קצת CSS. נעביר אותו לפינה העליונה, נגדיר אותו כך שימלא את כל המסך בצורה אנכית, ונחיל background-color ו-box-shadow.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
--nav-list-position: static;
--nav-list-padding: 0;
--nav-list-height: auto;
--nav-list-width: 100%;
--nav-list-shadow: none;
}
}
ul {
background: rgb(255, 255, 255);
box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
height: var(--nav-list-height, 100vh);
list-style: none;
margin: 0;
padding: var(--nav-list-padding, 2rem);
position: var(--nav-list-position, fixed);
inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
width: var(--nav-list-width, min(22rem, 100vw));
}
button {
all: unset;
display: var(--nav-button-display, flex);
position: relative;
z-index: 1;
}
הרשימה אמורה להיראות בערך כך באזורי תצוגה צרים, יותר כמו סרגל צד מאשר רשימה פשוטה.
לבסוף, מסתירים את הרשימה, מציגים אותה רק כשהמשתמש לוחץ על הכפתור פעם אחת ומסתירים אותה כשהוא לוחץ שוב. חשוב להסתיר רק את הרשימה ולא את כל הניווט, כי הסתרת הניווט תגרום גם להסתרת ציון דרך חשוב.
קודם הוספתם אירוע מסוג קליק ללחצן כדי להחליף את הערך של המאפיין aria-expanded. אתם יכולים להשתמש במידע הזה כתנאי להצגה ולהסתרה של הרשימה ב-CSS.
@media (min-width: 48em) {
ul {
--nav-list-visibility: visible;
}
}
ul {
visibility: var(--nav-list-visibility, visible);
}
/* Hide the list on narrow viewports, if it comes after an element with
aria-expanded set to "false". */
[aria-expanded="false"] + ul {
visibility: var(--nav-list-visibility, hidden);
}
כדי להסתיר את הרשימה, חשוב להשתמש בהצהרת מאפיין כמו visibility: hidden או display: none במקום opacity: 0 או translateX(100%). המאפיינים האלה מבטיחים שלא ניתן יהיה להתמקד בקישורים כשהניווט מוסתר. אם משתמשים ב-opacity או ב-translate, התוכן מוסר באופן חזותי, כך שהקישורים לא יהיו גלויים אבל עדיין תהיה גישה אליהם באמצעות המקלדת, וזה עלול להיות מבלבל ומתסכל. שימוש ב-visibility או ב-display מסתיר את התוכן באופן חזותי ומונע גישה אליו, ולכן הוא מוסתר מכל המשתמשים.
הנפשת הרשימה
אם אתם תוהים למה להשתמש ב-visibility: hidden; במקום ב-display: none;, זה בגלל שאפשר להוסיף אנימציה לניראות. יש לו רק שני מצבים, hidden ו-visible, אבל אפשר לשלב אותו עם מאפיין אחר כמו transform או opacity כדי ליצור אפקט של החלקה או הופעה הדרגתית. זה לא יעבוד עם display: none כי אי אפשר להוסיף אנימציה למאפיין display.
ה-CSS הבא משתמש במעברים של opacity כדי ליצור אפקט של הבהרה הדרגתית ועמעום הדרגתי.
ul {
transition: opacity 0.6s linear, visibility 0.3s linear;
visibility: var(--nav-list-visibility, visible);
}
[aria-expanded="false"] + ul {
opacity: 0;
visibility: var(--nav-list-visibility, hidden);
}
אם אתם רוצים להוסיף אנימציה לתנועה, כדאי לשקול לעטוף את המאפיין transition בשאילתת מדיה prefers-reduced-motion כי אנימציות יכולות לגרום לבחילות, סחרחורות וכאבי ראש אצל חלק מהמשתמשים.
ul {
visibility: var(--nav-list-visibility, visible);
}
@media (prefers-reduced-motion: no-preference) {
ul {
transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
}
}
[aria-expanded="false"] + ul {
transform: var(--nav-list-transform, translateX(100%));
visibility: var(--nav-list-visibility, hidden);
}
כך, רק אנשים שלא מעדיפים תנועה מופחתת יראו את האנימציה.
שיפור סגנון המיקוד
משתמשי מקלדת מסתמכים על סגנונות המיקוד של רכיבים כדי להתמצא ולנווט בדף. סגנונות ברירת המחדל של המיקוד טובים יותר מאשר ללא סגנונות מיקוד (מה שקורה אם מגדירים את outline: none), אבל סגנונות מיקוד מותאמים אישית שגלויים יותר משפרים את חוויית המשתמש.
כך נראים סגנונות ברירת המחדל של המיקוד בקישור ב-Chrome 103.
כדי לשפר את הניגודיות, אתם יכולים להגדיר סגנונות משלכם בצבעים שאתם בוחרים. כשמשתמשים ב-:focus-visible במקום ב-:focus, הדפדפן מחליט מתי מתאים להציג סגנונות מיקוד. סגנונות :focus יהיו גלויים לכולם, למשתמשים בעכבר, במקלדת ובמגע, לא משנה אם הם צריכים אותם או לא. עם :focus-visible, הדפדפן משתמש בהיוריסטיקה פנימית כדי להחליט אם להציג אותם רק למשתמשי מקלדת או לכולם.
/* Remove the default :focus outline */
*:focus {
outline: none;
}
/* Show a custom outline on :focus-visible */
*:focus-visible {
outline: 2px solid var(--color-shades-dark);
outline-offset: 4px;
}
תמיכה בדפדפן עבור :focus-visible
יש דרכים שונות להדגיש פריטים כשהם במיקוד. מומלץ להשתמש במאפיין outline כי הוא לא משבש את הפריסה, מה שיכול לקרות עם border, והוא פועל היטב עם מצב ניגודיות גבוהה ב-Windows. מאפיינים שלא פועלים היטב הם background-color או box-shadow, כי יכול להיות שהם לא יוצגו בכלל בהגדרות ניגודיות מותאמות אישית.
מעולה! יצרתם ניווט ראשי עם שיפור הדרגתי, עשיר מבחינה סמנטית, נגיש וידידותי לנייד.
תמיד יש משהו שאפשר לשפר, לדוגמה:
- אפשר לשקול ללכוד את המיקוד בתוך הניווט או להפוך את שאר הדף ללא פעיל באזורי תצוגה צרים.
- אתם יכולים להוסיף קישור לדילוג למקום מסוים בדף בחלק העליון של הדף כדי לאפשר למשתמשים במקלדת לדלג על הניווט.
אם אתם זוכרים איך המאמר הזה התחיל, עם המטרה שהפתרון לא יהיה "פשוט מדי ולא מסובך מדי", זה המקום שבו אנחנו נמצאים עכשיו. עם זאת, אפשר להגזים בתכנון של הניווט.
ניווט לעומת תפריטים
יש הבדל ברור בין ניווט לתפריטים. רכיבי ניווט הם אוספים של קישורים לניווט במסמכים קשורים. התפריטים הם אוספים של פעולות שאפשר לבצע במסמך. לפעמים המשימות האלה חופפות. יכול להיות שיש לכם רכיב ניווט שכולל גם כפתור שמבצע פעולה, כמו פתיחת חלון עזר, או שיש לכם תפריט שבו אחת הפעולות היא ניווט לדף אחר, כמו דף עזרה. במקרים כאלה, חשוב לא לערבב בין תפקידי ARIA, אלא לזהות את המטרה העיקרית של הרכיב ולבחור את תגי העיצוב והתפקידים בהתאם.
הרכיב <nav> כולל תפקיד ARIA משתמע של ניווט, שמספיק כדי להעביר את המסר שהרכיב הוא ניווט, אבל לעיתים קרובות רואים אתרים שמשתמשים גם בתפריט, בסרגל תפריטים ובפריט בתפריט. לפעמים אנחנו משתמשים במונחים האלה באופן חופשי, ולכן יכול להיות ששילוב שלהם כדי לשפר את החוויה של משתמשי קורא המסך נראה הגיוני. לפני שנבין למה זה בדרך כלל לא המצב, בואו נסתכל על ההגדרה הרשמית של התפקידים האלה.
תפקיד הניווט
אוסף של רכיבי ניווט (בדרך כלל קישורים) לניווט במסמך או במסמכים קשורים.
ניווט (תפקיד) WAI-ARIA 1.1
תפקיד התפריט
תפריט הוא בדרך כלל רשימה של פעולות או פונקציות נפוצות שהמשתמש יכול להפעיל. התפקיד של התפריט מתאים כשמוצגת רשימה של פריטי תפריט באופן שדומה לתפריט באפליקציה למחשב.
תפריט (תפקיד) WAI-ARIA 1.1
התפקיד של סרגל התפריטים
תצוגה של תפריט שבדרך כלל נשאר גלוי ומוצג בצורה אופקית. התפקיד menubar משמש ליצירת סרגל תפריטים שדומה לאלה שנמצאים באפליקציות לשולחן העבודה של Windows, Mac ו-Gnome. סרגל תפריטים משמש ליצירת קבוצה עקבית של פקודות נפוצות. היוצרים צריכים לוודא שהאינטראקציה עם סרגל התפריטים דומה לאינטראקציה הרגילה עם סרגל התפריטים בממשק משתמש גרפי במחשב.
menubar (role) WAI-ARIA 1.1
התפקיד menuitem
אפשרות בקבוצה של אפשרויות בחירה שכלולות בתפריט או בסרגל תפריטים.
menuitem (role) WAI-ARIA 1.1
המפרט מאוד ברור בנושא הזה: צריך להשתמש בניווט כדי לנווט במסמך או במסמכים קשורים, ולהשתמש בתפריט רק לרשימה של פעולות או פונקציות שדומות לתפריטים באפליקציות למחשב. אם אתם לא מפתחים את הגרסה הבאה של Google Docs, כנראה שאתם לא צריכים אף אחד מהתפקידים של התפריט לניווט הראשי.
מתי מתאים להשתמש בתפריט?
המטרה העיקרית של פריטים בתפריט היא לא ניווט, אלא ביצוע פעולות. נניח שיש לכם רשימה או טבלה של נתונים, והמשתמשים יכולים לבצע פעולות מסוימות בכל פריט ברשימה. אפשר להוסיף כפתור לכל שורה ולהציג את הפעולות כשהמשתמשים לוחצים על הכפתור.
<ul>
<li>
Product 1
<button aria-expanded="false" aria-controls="options1">Edit</button>
<div role="menu" id="options1">
<button role="menuitem">
Duplicate
</button>
<button role="menuitem">
Delete
</button>
<button role="menuitem">
Disable
</button>
</div>
</li>
<li>
Product 2
...
</li>
</ul>
ההשלכות של שימוש בתפקידי תפריט
חשוב מאוד להשתמש בתפקידי התפריט האלה בחוכמה, כי הרבה דברים יכולים להשתבש.
התפריטים מצפים למבנה DOM מסוים. menuitem חייב להיות פריט צאצא ישיר של menu. הקוד הבא עלול לשבש את ההתנהגות הסמנטית:
<!-- Wrong, don't do this -->
<ul role="menu">
<li>
<a href="#" role="menuitem">Item 1</a>
</li>
</ul>
משתמשים מנוסים מצפים שמקשי קיצור מסוימים יפעלו עם תפריטים וסרגלי תפריטים. בהתאם ל-ARIA Authoring Practices Guide (APG), זה כולל:
- Enter ומקש הרווח כדי לבחור אפשרויות בתפריט.
- מקשי החיצים לכל הכיוונים כדי לנווט בין פריטים.
- המקשים Home ו-End כדי להעביר את המיקוד לפריט הראשון או האחרון, בהתאמה.
- a-z כדי להעביר את המיקוד לפריט הבא בתפריט עם תווית שמתחילה בתו שהוקלד.
- Esc כדי לסגור את התפריט.
אם קורא המסך מזהה תפריט, התוכנה עשויה לשנות באופן אוטומטי את מצב הגלישה, ולאפשר שימוש בקיצורי הדרך שצוינו קודם. יכול להיות שמשתמשים לא מנוסים בקורא מסך לא יוכלו להשתמש בתפריט כי הם לא מכירים את מקשי הקיצור האלה או לא יודעים איך להשתמש בהם.
זה נכון גם לגבי משתמשים שמשתמשים במקלדת, שאולי מצפים שהם יוכלו להשתמש ב-Shift וב-Shift + Tab.
יש הרבה דברים שצריך להביא בחשבון כשיוצרים תפריטים וסרגלי תפריטים, והדבר הכי חשוב הוא אם בכלל מתאים להשתמש בהם. כשבונים אתר רגיל, רכיב הניווט עם רשימה וקישורים הוא כל מה שצריך. זה כולל גם אפליקציות דף יחיד (SPA) או אפליקציות אינטרנט. המחסנית הבסיסית לא משנה. אלא אם אתם בונים משהו שדומה מאוד לאפליקציה למחשב, הימנעו מתפקידי תפריט.
מקורות מידע נוספים
- Fixing Lists (תיקון רשימות) מאת סקוט אוהרה.
- Don't Use ARIA Menu Roles for Site Nav (אל תשתמשו בתפקידי תפריט של ARIA לניווט באתר) מאת אדריאן רוסלי.
- Menus & Menu Buttons (תפריטים וכפתורי תפריטים) מאת היידון פיקרינג.
- תפריטי WAI-ARIA, ולמה צריך לטפל בהם בזהירות רבה, מאת מרקו זהה.
- הסתרה אחראית של תוכן, מאת קיטי ג'יראודל (Kitty Giraudel).
- :focus-visible Is Here מאת Matthias Ott.