בניית הניווט הראשי לאתר

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

Manuel Matuzović
Manuel Matuzović

יש הרבה דרכים שונות לבנות את תפריט הניווט הראשי של אתר, מבחינת העיצוב, הפונקציונליות, הרכיבים הבסיסיים של ה-Markup והמידע הסמנטי. אם ההטמעה מינימליסטית מדי, היא תעשה את העבודה עבור רוב האנשים, אבל יכול להיות שחוויית המשתמש (UX) לא תהיה טובה. אם המערכת מורכבת מדי, היא עלולה לבלבל את המשתמשים או אפילו למנוע מהם לגשת אליה בכלל.

ברוב האתרים, כדאי ליצור משהו שלא פשוט מדי ולא מסובך מדי.

שכבה אחר שכבה

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

מבנה בסיסי

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

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* 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);
}
לצפייה בשלב 1: HTML בסיסי ו-CSS" ב-CodePen.

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

אתם יכולים לבצע את הפעולות הבאות:

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

הדגשת הדף הפעיל

כדי להדגיש את הדף הפעיל, אפשר להוסיף סיווג לקישור המתאים.

<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);
}
שלב 2: מדגישים את הדף הפעיל ב-CodePen

הקראה של מספר הפריטים

משתמשים שרואים יכולים לראות שבתפריט הניווט יש רק ארבעה קישורים. משתמש עיוור בקורא מסך לא יכול לקבל את המידע הזה במהירות כזו. יכול להיות שהם יצטרכו לעבור על כל רשימת הקישורים. יכול להיות שהבעיה הזו לא תהיה רלוונטית אם הרשימה קצרה כמו בדוגמה הזו, אבל אם היא מכילה 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>
לצפייה בשלב 3: הכרזה על מספר הפריטים ב-CodePen.

הוספת ציון דרך

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

יש כמה יתרונות לשימוש ברכיב <nav>. חשוב לציין שקורא מסך מכריז על משהו כמו 'ניווט', כשהמשתמש מקיים אינטראקציה עם הדף, ומוסיף ציון דרך לדף. ציוני דרך הם אזורים מיוחדים בדף, כמו <header>, <footer> או <main>, שאליהם קורא מסך יכול להגיע. כדאי להוסיף נקודות ציון לדף כי הן מאפשרות למשתמשים בקורא מסך לגשת ישירות לאזורים חשובים בדף בלי צורך באינטראקציה עם שאר הדף. לדוגמה, אפשר לדלג מציון דרך אחד למשנהו על ידי לחיצה על המקש D ב-NVDA. ב-VoiceOver, אפשר להשתמש בבורר כדי לקבל רשימה של כל נקודות הציון בדף. לשם כך, מקישים על VO + U.

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

ברשימה הזו מופיעים 4 מאפיינים: באנר, שהוא הרכיב <header>, ניווט, שהוא הרכיב <nav>, ראשי, שהוא הרכיב <main> ופרטי תוכן, שהוא הרכיב <footer>. הרשימה הזו לא צריכה להיות ארוכה מדי. מומלץ לסמן רק חלקים קריטיים בממשק המשתמש בתור ציוני דרך, כמו חיפוש באתר, ניווט מקומי או חלוקה לדפים.

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

תמונה שרואים בה שלושה ציוני דרך שלכולם כתוב &#39;ניווט&#39;.
החוגה של VoiceOver עם רשימה של שלושה ציוני דרך לניווט ללא תוויות.

כדי להבדיל ביניהם, צריך לתייג אותם באמצעות 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>

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

ציוני דרך
VoiceOver מציין את ציוני הדרך הבאים: 'מודעת באנר', 'ניווט ראשי', 'ראשית', 'ניווט בדפים', 'בחירת ניווט בדפים' ו'פרטי תוכן'.
לצפייה בשלב 4: הוספת ציון דרך ב-CodePen.

הסתרת הניווט בחלונות צפייה צרים

באופן אישי, אני לא אוהב להסתיר את הניווט הראשי בחלונות צפייה צרים, אבל אם רשימת הקישורים ארוכה מדי, אין מנוס מכך. במקרה כזה, במקום הרשימה, המשתמשים יראו לחצן עם הכיתוב 'תפריט' או סמל המבורגר או שילוב של שניהם. לחיצה על הלחצן מציגה ומסתירה את הרשימה. אם יש לכם ידע בסיסי ב-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>
  1. המאפיין aria-expanded מאפשר לתוכנה של קורא המסך לדעת אם הרכיב שהלחצן שולט בו מורחב או לא.
  2. aria-label נותן ללחצן שם נגיש, שהוא טקסט חלופי לסמל של ההמבורגר.
  3. אתם מסתירים את <svg> מטכנולוגיה מסייעת באמצעות aria-hidden כי כבר יש לו תווית טקסט שסופקה על ידי aria-label.
  4. 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);
  1. המשתמשים יכולים לסגור את הניווט מתי שהם רוצים, למשל על ידי הקשה על המקש Escape.
  2. חשוב להשתמש ב-insertBefore במקום ב-appendChild כי הלחצן צריך להיות הרכיב הראשון בתפריט הניווט. אם משתמש במקלדת או בקורא מסך לוחץ על Tab אחרי שהוא לוחץ על הלחצן, הוא מצפה שההתמקדות תעבור לפריט הראשון ברשימה. אם הלחצן מופיע אחרי הרשימה, זה לא המצב.

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

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
שלב 5: הוספת לחצן המבורגר ב-CodePen

הסתרת הרשימה

לפני שמסתירים את הרשימה, צריך למקם את התפריט ואת הרשימה ולקבוע את הסגנון שלהם כך שהפריסה תהיה אופטימלית לתצוגות חלון מצומצמות, אבל עדיין תיראה טוב במסכים גדולים יותר.
תחילה, מסירים את <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 מסתיר אותו באופן חזותי ולא מאפשר גישה אליו, כך שהוא מוסתר מכל המשתמשים.

שלב 6: הסתרת הרשימה

הצגת הרשימה באנימציה

אם אתם תוהים למה כדאי להשתמש ב-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);
}

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

שלב 7: הוספת אנימציה לרשימה ב-CodePen

שיפור העיצוב של המיקוד

משתמשים במקלדת מסתמכים על סגנונות המיקוד של רכיבים כדי לנווט בדף. סגנונות ברירת המחדל של התמקדות טובים יותר מאשר לא להשתמש בסגנונות התמקדות (מה שקורה אם מגדירים את הערך outline: none), אבל שימוש בסגנונות התמקדות מותאמים אישית שגלויים יותר משפר את חוויית המשתמש.

כך נראים סגנונות המיקוד שמוגדרים כברירת מחדל בקישור ב-Chrome 103.

קו מתאר כחול של 2 פיקסלים מסביב לקישור ממוקד ב-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

תמיכה בדפדפנים

  • Chrome:‏ 86.
  • Edge:‏ 86.
  • Firefox:‏ 85.
  • Safari: 15.4.

מקור

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

יש דרכים שונות להדגשת פריטים בזמן המיקוד. מומלץ להשתמש במאפיין outline כי הוא לא מקוטע את הפריסה, מה שעלול לקרות עם border, והוא פועל היטב עם מצב ניגודיות גבוהה ב-Windows. נכסים שלא פועלים טוב הם background-color או box-shadow, כי יכול להיות שהם לא יוצגו בכלל עם הגדרות ניגודיות מותאמות אישית.

אתר עם רקע כהה והדגש מודגש בסגול.
שלב 8: שיפור סגנונות המיקוד ב-CodePen

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

תמיד יש משהו שאפשר לשפר, למשל:

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

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

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

לרכיב <nav> יש תפקיד ARIA משתמע של ניווט, שהוא מספיק כדי להעביר את המסר שהרכיב הוא רכיב ניווט, אבל לעיתים קרובות אפשר לראות באתרים גם שימוש ברכיבים menu,‏ menubar ו-menuitem. לפעמים אנחנו משתמשים במונחים האלה ללא הבחנה, ולכן נראה ששילוב שלהם יכול לשפר את החוויה של משתמשים שנעזרים בקורא מסך. לפני שנראה למה בדרך כלל זה לא המצב, נבחן את ההגדרה הרשמית של התפקידים האלה.

תפקיד הניווט

אוסף של אלמנטים ניווטיים (בדרך כלל קישורים) לניווט במסמך או במסמכים קשורים.

navigation (תפקיד) WAI-ARIA 1.1

תפקיד התפריט

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

menu (תפקיד) WAI-ARIA 1.1

התפקיד של סרגל התפריטים

תצוגה של תפריט שבדרך כלל נשאר גלוי ומוצג בדרך כלל לרוחב. התפקיד menubar משמש ליצירת סרגל תפריטים שדומה לסרגלי תפריטים שנמצאים באפליקציות למחשב של Windows,‏ Mac ו-Gnome. סרגל תפריטים משמש ליצירת קבוצה עקבית של פקודות נפוצות. צריך לוודא שהאינטראקציה עם שורת התפריטים דומה לאינטראקציה הרגילה עם שורת התפריטים בממשק משתמש גרפי במחשב.

menubar (role) WAI-ARIA 1.1

התפקיד menuitem

אפשרות בקבוצת אפשרויות שכלולה בתפריט או בסרגל תפריטים.

menuitem (תפקיד) 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 (APG), הדברים האלה כוללים:

  • מקישים על Enter ועל מקש הרווח כדי לבחור אפשרויות בתפריט.
  • כדי לנווט בין פריטים, מקישים על מקשי החיצים בכל הכיוונים.
  • כדי להעביר את המיקוד לפריט הראשון או האחרון, בהתאמה, מקישים על Home (בית) ו-End (סיום).
  • a-z כדי להעביר את המיקוד לפריט התפריט הבא עם תווית שמתחילה בתו שהוקלד.
  • מקישים על Esc כדי לסגור את התפריט.

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

אותו הדבר לגבי משתמשי מקלדת שעשויים לצפות שיוכלו להשתמש ב-Shift וב-Shift + Tab.

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

משאבים נוספים

תמונה ראשית (Hero) של Mick Haupt