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

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

Manuel Matuzović
Manuel Matuzović

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

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

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

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