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

במדריך הזה נסביר איך ליצור ממשק ניווט ראשי נגיש באתר. תלמדו על 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=&quot;page&quot; במקום במחלקה.

aria-current (מצב) מציין את הרכיב שמייצג את הפריט הנוכחי בתוך מאגר או קבוצה של רכיבים קשורים. אסימון דף המשמש לציון קישור בתוך קבוצה של קישורי חלוקה לדפים, כאשר הקישור מעוצב באופן חזותי כך שהוא ייצג את הדף הנוכחי שמוצג. [אפליקציות אינטרנט עשירות (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)

עם המאפיין הנוסף, קורא מסך מכריז עכשיו על משהו כמו "הדף הנוכחי, קישור, מי אנחנו" ולא רק "link, About Us".

<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>

כשמשתמש בקורא מסך מוצא את הרשימה, התוכנה תכריז על משהו כמו "list, 4 items".

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

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

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

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.
  • קצה: 86.
  • Firefox: 85.
  • Safari: 15.4.

מקור

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

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

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

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

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

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

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

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

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

תפקיד הניווט

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

ניווט (תפקיד) WAI-ARIA 1.1

תפקיד התפריט

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

תפריט (תפקיד) WAI-ARIA 1.1

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

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

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

התפקיד של פריט בתפריט

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

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