ناوبری اولیه یک وب سایت برای قابلیت استفاده و دسترسی آن بسیار مهم است. با این حال، سیستم های ناوبری به طرز فریبنده ای پیچیده هستند. همه به جز ساده ترین وب سایت ها باید با این موضوع کنار بیایند.

با نسخه 9.4، دروپال یک تم پیش فرض کاملاً جدید به نام Olivero دارد. به عنوان پیش فرض، می دانستیم که سیستم ناوبری آن در طول عمرش توسط صدها میلیون (اگر نه میلیاردها) کاربر استفاده می شود. و از همه چیزهایی که با موضوع جدید دروپال به آنها افتخار می کنیم، سیستم ناوبری در صدر فهرست قرار دارد. مقدار زیادی آزمایش، رفع اشکال و مراقبت انجام شد.

قابل استفاده، در دسترس، قوی، و زیبا

وقتی شروع به ایجاد تم کردیم، می دانستیم که باید قابل استفاده، در دسترس، قوی و زیبا باشد. همه این اهداف چالش های مهمی را به همراه دارند.

برای قابلیت استفاده، ما می‌خواستیم فهرست‌های بازشوی ناوبری سطح دوم مشابه بسیاری از سایت‌های موجود در اینترنت را اضافه کنیم. این منوهای کشویی ناوبری سطح دوم باید با شناور، کلیک و لمس باز شوند.

دسترسی یک گیت اصلی دروپال است. ما می دانستیم که باید استانداردهای WCAG 2.1 AA را برآورده کند یا از آن فراتر رود. بیشتر از فقط ملاقات استانداردها، ما می خواهیم موضوع ما برای کسانی که نیاز به استفاده از فناوری کمکی دارند لذت بخش باشد.

و چون ما محتوا را کنترل نمی کنیم، سیستم منو باید بسیار قوی باشد. نمی دانیم که ویرایشگرهای محتوا یک مورد وارد می کنند یا صدها مورد! ما کنترلی روی طول متن نداریم. ما همچنین از بین‌المللی‌سازی پشتیبانی می‌کنیم که شامل پشتیبانی از زبان‌های راست به چپ مانند عربی می‌شود.

علاوه بر این قابلیت، منو نیز باید زیبا باشد. طراحان ما کار شگفت انگیزی را انجام دادند و آن را به سخره گرفتند، و سپس ما برخی از انتقال های اساسی CSS را ادغام کردیم تا یک انیمیشن کم رنگ و عمودی تبدیل شده را اضافه کنیم.

منوی اولیورو با یک استاندارد شروع می شود <nav> عنصر یک را اضافه می کنیم aria-labelledby مشخصه اشاره به شناسه بصری پنهان (اما قابل دسترسی برای صفحه خوان) h2 عنصر این نام پیمایش را به افرادی که از صفحه‌خوان‌ها استفاده می‌کنند، منتقل می‌کند تا بتوانند عناصر ناوبری مختلف را متمایز کنند. همچنین به کاربران این امکان را می دهد که در صورت پیمایش بر اساس عنوان، این منو را پیدا کنند.

آیتم های منو به یک تغییر تکیه می کنند الگوی افشای پیوند هنگام استفاده از هایپرلینک ها به عنوان آیتم ناوبری سطح بالا.

توجه داشته باشید: دروپال همچنین می تواند از a استفاده کند <button> عنصر به عنوان آیتم سطح بالا.

این الگو الف را تزریق می کند <button> عنصر بعد از هایپرلینک در Olivero، ما دکمه را با نماد “down chevron” استایل می کنیم.

منوی پیوند با عنصر دکمه مجاور، با منوی کشویی در زیر
الگوی افشای پیوند (پیش نمایش بزرگ)

دکمه دارد aria-controls (به شناسه تو در تو نگاشت شده است <ul>) و aria-expanded ویژگی هایی که با جاوا اسکریپت مقداردهی اولیه می شوند. اگر سایت بدون جاوا اسکریپت بارگذاری شود، دکمه ها صرفاً نمایشی می شوند.

این دکمه حاوی متن پنهان بصری با متن آیتم منو و به دنبال آن «sub-navigation» است. این به این دلیل است که افرادی که بین کنترل‌های فرم قرار می‌گیرند، می‌توانند بفهمند که دکمه چه منویی را کنترل می‌کند.

<nav aria-labelledby="block-olivero-main-menu-menu">
  <h2 class="visually-hidden" id="block-olivero-main-menu-menu">Main navigation</h2>
  <ul>
    <li>
      <a href="https://smashingmagazine.com/">Webforms</a>
      <button aria-controls="primary-menu-item-12" aria-expanded="false">
        <span class="visually-hidden">Webforms sub-navigation</span>
      </button>
      <ul id="primary-menu-item-12">
        <!-- Submenu items -->
      </ul>
    </li>
    <!-- More top-level navigation items here. -->
  </ul>
</nav>
بیشتر بعد از پرش! ادامه مطلب زیر ↓

منوهای فرعی با شناور، کلیک و ضربه زدن باز می شوند. با این حال، ما باید اطمینان حاصل کنیم که این رویدادها به طور همزمان اجرا نمی شوند (مثل اینکه در دستگاه های لمسی می توانند فعال شوند) زیرا اگر منو فوراً باز و بسته شود، به نظر می رسد که هیچ اتفاقی نیفتاده است! ما همچنین باید فناوری کمکی مانند ابزارهای اسکن نقطه ای را در نظر بگیریم که ممکن است هر دو رویداد را به صورت متوالی به راه بیندازند.

ابزار اسکن اشاره گر MacOS در عمل (سرعت بالا).

برای تطبیق همه اینها، ما به یک گوش می دهیم touchstart رویداد و در صورت وجود، از آن بگذرید mouseover پردازش رویداد اگر و زمانی که mouseover فرآیندهای رویداد، ما آن را غیرفعال می کنیم click رویداد از انجام هر کاری برای نیم ثانیه. و در نهایت وقتی رویداد کلیک پردازش می شود، زیر منو را نشان می دهیم. منطق کمی پیچیده می شود، اما با هر فناوری کمکی قابل استفاده است.

زمانی که شرایط خاصی برآورده شد، منوهای فرعی باید بسته شوند:

  • اگر کلید Escape فشار داده شود، منوی فرعی بسته می شود و فوکوس به آیتم والد باز می گردد.
  • اگر یک mouseout رویداد رخ می دهد، منوی فرعی بسته می شود مگر اینکه فوکوس در زیر منو قرار دارد.
  • به طور مشابه، زیر منوها در بسته خواهند شد blur رویدادی برای اطمینان از اینکه زیر منوها نمی توانند یکدیگر را پنهان کنند (و به طور بالقوه معیار موفقیت قابل مشاهده تمرکز WCAG 2.4.7 را نقض می کنند).

از آنجایی که موضوع نمی تواند تعداد آیتم های منو را که کاربر وارد می کند کنترل کند، باید مقدار نامحدودی را در نظر بگیریم. ما گزینه ای برای روشن کردن منوی تلفن همراه (که می تواند موارد نامحدودی را در خود جای دهد) در تمام عرض های صفحه ایجاد کردیم. اما هنوز یک مورد لبه وجود دارد که ممکن است آیتم های کافی در عرض های متوسط ​​وجود داشته باشد تا منوی بسته بندی یا سرریز شود.

منوی پیچیده با موارد بسیار زیاد
منو در حال بسته بندی است زیرا موارد زیادی در یک درگاه دید باریک دارد. (پیش نمایش بزرگ)

برای انجام این کار، وقتی فضای منوی اصلی تمام شد، به منوی تلفن همراه تغییر می کنیم. برای انجام این کار، یک ناظر تغییر اندازه را تنظیم می کنیم تا بررسی کند که آیا متن پیچیده شده است یا خیر. اگر اینطور است، ما منوی موبایل را فعال می کنیم و به یاد می آوریم که چه زمانی باید به نسخه دسکتاپ برگردیم (در صورت بزرگ شدن پنجره دید).

const navMenu = document.querySelector('.primary-nav');
const navItem = navMenu.querySelector('.primary-nav__menu-item');

function checkIfDesktopNavigationWraps() {
  if (isDesktopNav() && navMenu.height > navItem.clientHeight) {
    enableMobileNav(); // Enable the mobile navigation.
    // Remember when to switch back to desktop navigation.
    const navMediaQuery = window.matchMedia(`(max-width: ${window.innerWidth + 15}px)`);
    navMediaQuery.addEventListener('change', () => {
      // Double check to see if the navigation is wrapping to prevent edge
      // cases where the mobile menu should still be enabled.
      if (navMenu.clientHeight > navItem.clientHeight) {
        disableMobileNav(navMenu, navItem);
      }
    }, { once: true });
  }
}

const resizeObserver = new ResizeObserver(checkIfDesktopNavigationWraps);
resizeObserver.observe(navMenu);
اسکرین شات با فعال بودن منوی موبایل
خیلی بهتر. منوی تلفن همراه اکنون فعال است زیرا پیمایش دسکتاپ نمی تواند همه موارد منو را در خود جای دهد. (پیش نمایش بزرگ)

منوی اولیورو در بالای پنجره دید ثابت است. اگر درگاه دید کوتاه‌تر از طولانی‌ترین منوی فرعی باشد، منوهای ثابت می‌توانند مشکل ایجاد کنند – کاربر هرگز نمی‌تواند برای دسترسی به موارد در انتها پیمایش کند. این ناتوانی در دسترسی به موارد در انتهای منو باعث ایجاد یک شکست دیگر می شود WCAG 2.4.7 Focus Visible.

تصویری که در آن آیتم‌های منوی طولانی در زیر درگاه نمایش غیرقابل دسترسی هستند
با یک هدر ثابت و درگاه دید کوتاه، آیتم‌های منوی طولانی با پیمایش یا تب کردن قابل دسترسی نیستند. (پیش نمایش بزرگ)

این را با محاسبه ارتفاع هدر و تنظیم حل می کنیم max-height و overflow: auto در زیر منو

.submenu {
  max-height: calc(100vh - var(--header-height));
  overflow: auto;
}

با وجود این سبک‌ها، منو هرگز بزرگ‌تر از ارتفاع درگاه نمایش نمی‌شود و مرورگر تنها در صورت نیاز منوی فرعی را قابل پیمایش می‌کند. اگر کاربر در پایین منوی فرعی قرار بگیرد، مرورگر به طور خودکار محتوا را برای مشاهده اسکرول می کند.

تصویری که در آن منوی فرعی دارای یک نوار پیمایش است
با اعمال سبک‌ها، اگر محتوا بزرگ‌تر از ارتفاع درگاه دید باشد، زیرمنو یک نوار پیمایش دریافت می‌کند. (پیش نمایش بزرگ)

پشتیبانی غیر جاوا اسکریپت

از آنجا که دروپال نشانه گذاری خود را روی سرور ارائه می کند، ما این فرصت را داریم که از دستگاه هایی که جاوا اسکریپت غیرفعال است پشتیبانی کنیم. برای تحقق این امر، ما را فعال می کنیم :hover و :focus-within در آیتم منوی والد

body:not(.js) .menu-item:is(:hover, :focus-visible) .menu-level-2 {
  visibility: visible;
}

منوی موبایل Olivero همان طور که انتظار دارید عمل می کند. به شناورها واکنش نشان نمی دهد، اما ویژگی های آریا ثابت می مانند.

ناوبری موبایل اولیورو
(پیش نمایش بزرگ)

ناوبری تلفن همراه توسط a فعال می شود <button> عنصر پنهان در عرض دسکتاپ این دکمه همچنین شامل aria-expanded و aria-controls عناصر با مقادیر مناسب

با کلیک بر روی دکمه، منو باز می شود و می توانید با کلیک کردن (یا ضربه زدن) در خارج از منو، منو را ببندید. علاوه بر این در رفتن کلید منو را می بندد و فوکوس را روی دکمه منوی موبایل برمی گرداند.

مدیریت تمرکز در داخل منو

منوی موبایل Olivero خود را بر محتوای صفحه قرار می دهد. اگر محتوای پنهان شده توسط منو تمرکز پیدا کند، می تواند مشکل دسترسی ایجاد کند.

برای حل این مشکل، یک “تله تمرکز” در منو و دکمه بستن آن ایجاد می کنیم. این تضمین می کند که اگر کاربر از طریق صفحه کلید در سایت حرکت کند، نمی تواند در خارج از منو تمرکز کند.

ما با یک موقعیت واقعی روبرو شدیم که در آن کاربر یک پیوند لنگر را در منو وارد کرد. پس از کلیک کردن، سایت به صفحه پایین می رود، اما منو همچنان باز است.

برای رفع این مشکل، مقداری جاوا اسکریپت اضافه می کنیم که در صورتی که پیوند هدف لنگر باشد، ناوبری موبایل را می بندد.

// If hyperlink links to an anchor in the current page, close the mobile menu after click.
navWrapper.addEventListener('click', (e) => {
  if (e.target.matches(`[href*="${window.location.pathname}#"], [href^="#"]`)) {
    closeNavigation();
  }
});

برای پشتیبانی از منوی موبایل بدون جاوا اسکریپت، باید منو را بدون فشار دادن دکمه منوی باز (که آن را پنهان می کنیم، نمایش دهیم، زیرا بدون جاوا اسکریپت کار نمی کند).

برای جلوگیری از فلش منوی غیر جاوا اسکریپت در بارگذاری صفحه، ما شیوه نامه غیر جاوا اسکریپت را در یک <noscript> برچسب در <head>. این بدان معناست که مرورگر این سبک‌ها را پردازش نمی‌کند مگر اینکه جاوا اسکریپت غیرفعال باشد.

سبک های تمرکز و رنگ های اجباری

سبک های تمرکز

تم Olivero دارای سبک های فوکوس بسیار قوی است که با ظاهر و احساس تم مطابقت دارد. سبک های فوکوس جنبه بسیار مهمی از دسترسی هستند که ما نمی خواستیم از آن غافل شویم.

سبک های تمرکز
(پیش نمایش بزرگ)

حالت رنگ های اجباری

تم Olivero و سیستم ناوبری آن به طور گسترده در رنگ های اجباری با استفاده از حالت کنتراست بالا ویندوز آزمایش شده است. علاوه بر مایکروسافت اج، در کروم و فایرفاکس نیز تست انجام می دهیم. ما همچنین آن را در چندین طرح رنگی با کنتراست بالا آزمایش کردیم، از جمله نور در تاریکی، تاریکی در روشنایی، و چند طرح سفارشی که ایجاد کردیم.

حالت رنگ های اجباری
(پیش نمایش بزرگ)

همه نمادها یا با استفاده از حاشیه ها (که در رنگ های اجباری آشکار می شوند) ایجاد می شوند یا از آن استفاده می کنند forced-colors: active پرس و جو رسانه برای اطمینان از قابل مشاهده بودن آن در هر طرح رنگی. علاوه بر این، ما از CanvasText رنگ سیستم برای تنظیم رنگ پس‌زمینه روکش، که یک مرز بصری برای منوی موبایل فراهم می‌کند.

دسترسی یک سفر است

برای برآوردن نیازهای خود، Olivero را به طور گسترده بر روی دستگاه‌های مختلف و فناوری کمکی آزمایش کردیم. ما همچنین با فدراسیون ملی نابینایان کار کردیم تا آزمایش‌های بیشتری برای صفحه‌خوان انجام دهیم. در طول مسیر، ما درس ها و تکنیک های زیادی آموختیم تا اطمینان حاصل کنیم که سیستم ناوبری Olivero برای همه افرادی که از هر نوع دستگاهی استفاده می کنند قابل استفاده است.

همانطور که گفته شد، دسترسی یک سفر است. بدون شک مشکلات دسترسی باقی مانده است که در طول عمر این طرح زمینه ظاهر می شوند، و ما آنها را در صورت وقوع برطرف خواهیم کرد. کد است GPL منبع باز رایگان (نمونه های بالا ساده شده است)، و امیدواریم که بتوانید از این درس ها برای بهبود سیستم های ناوبری در سراسر وب بهره مند شوید.

سرمقاله Smashing
(yk, il)