راهنمای جامع دسترسیپذیری نمای درختی، شامل نقشهای ARIA، ناوبری با کیبورد، بهترین شیوهها و سازگاری بین مرورگرها برای تجربه کاربری بهتر.
نمای درختی: دسترسیپذیری ناوبری دادههای سلسلهمراتبی
نماهای درختی (Tree views) مؤلفههای ضروری رابط کاربری (UI) برای نمایش دادههای سلسلهمراتبی هستند. آنها به کاربران اجازه میدهند تا ساختارهای پیچیده، مانند سیستمهای فایل، چارتهای سازمانی یا منوهای وبسایت را به شیوهای بصری پیمایش کنند. با این حال، یک نمای درختی که به درستی پیادهسازی نشده باشد، میتواند موانع قابل توجهی برای دسترسیپذیری ایجاد کند، به ویژه برای کاربرانی با معلولیت که به فناوریهای کمکی مانند صفحهخوانها و ناوبری با کیبورد متکی هستند. این مقاله یک راهنمای جامع برای طراحی و پیادهسازی نماهای درختی دسترسپذیر ارائه میدهد تا تجربه کاربری مثبتی را برای همه تضمین کند.
درک ساختار نمای درختی
یک نمای درختی دادهها را در یک قالب سلسلهمراتبی و قابل باز و بسته شدن (expandable/collapsible) نمایش میدهد. هر گره (node) در درخت میتواند گرههای فرزند داشته باشد و شاخهها و زیرشاخهها را ایجاد کند. بالاترین گره، گره ریشه (root node) نامیده میشود. درک ساختار پایه قبل از پرداختن به ملاحظات دسترسیپذیری، حیاتی است.
در ادامه، تفکیکی از عناصر رایج نمای درختی ارائه شده است:
- درخت (Tree): عنصر نگهدارنده کلی که کل ساختار درخت را در بر میگیرد.
- آیتم درخت (Treeitem): نمایانگر یک گره واحد در درخت است. این گره میتواند یک شاخه (قابل باز و بسته شدن) یا یک برگ (بدون فرزند) باشد.
- گروه (Group): (اختیاری) یک نگهدارنده که به صورت بصری آیتمهای فرزند را در یک آیتم والد گروهبندی میکند.
- آیکون باز/بسته کردن (Toggler/Disclosure Icon): یک نشانگر بصری (مانند علامت مثبت یا منفی، یا یک پیکان) که به کاربران اجازه میدهد یک شاخه را باز یا بسته کنند.
- برچسب (Label): متنی که برای هر آیتم درخت نمایش داده میشود.
اهمیت نقشها و ویژگیهای ARIA
برنامههای کاربردی اینترنتی غنی دسترسپذیر (Accessible Rich Internet Applications - ARIA) مجموعهای از ویژگیها هستند که معنای مفهومی به عناصر HTML اضافه میکنند و آنها را برای فناوریهای کمکی قابل فهم میسازند. هنگام ساخت نماهای درختی، نقشها و ویژگیهای ARIA برای انتقال ساختار و رفتار درخت به صفحهخوانها بسیار حیاتی هستند.
نقشهای ضروری ARIA:
role="tree"
: به عنصر نگهدارندهای که کل درخت را نمایندگی میکند، اعمال میشود. این نقش به فناوریهای کمکی اطلاع میدهد که این عنصر شامل یک لیست سلسلهمراتبی است.role="treeitem"
: به هر گره در درخت اعمال میشود. این نقش هر گره را به عنوان یک آیتم در داخل درخت شناسایی میکند.role="group"
: به عنصر نگهدارندهای که به صورت بصری آیتمهای فرزند را گروهبندی میکند، اعمال میشود. اگرچه همیشه ضروری نیست، اما میتواند معناشناسی را بهبود بخشد.
ویژگیهای کلیدی ARIA:
aria-expanded="true|false"
: به آیتمهایی که فرزند دارند اعمال میشود. نشان میدهد که آیا شاخه در حال حاضر باز (true
) است یا بسته (false
). این ویژگی باید به صورت پویا با استفاده از جاوا اسکریپت با باز و بسته شدن گره توسط کاربر بهروز شود.aria-selected="true|false"
: به آیتمها برای نشان دادن اینکه آیا گره در حال حاضر انتخاب شده است یا خیر، اعمال میشود. فقط یک گره باید در هر زمان انتخاب شود (مگر اینکه برنامه شما نیاز به انتخاب چندگانه داشته باشد، که در این صورت باید ازaria-multiselectable="true"
بر روی عنصر باrole="tree"
استفاده کنید).aria-label="[label text]"
یاaria-labelledby="[ID of label element]"
: یک برچسب توصیفی برای درخت یا آیتمهای جداگانه فراهم میکند. اگر برچسب به صورت بصری وجود ندارد ازaria-label
استفاده کنید؛ در غیر این صورت، ازaria-labelledby
برای مرتبط کردن آیتم با برچسب بصری آن استفاده کنید.tabindex="0"
: به آیتمی که در ابتدا فوکوس میشود (معمولاً اولین آیتم) اعمال میشود. برای سایر آیتمها ازtabindex="-1"
استفاده کنید تا زمانی که فوکوس روی آنها قرار گیرد (مثلاً از طریق ناوبری با کیبورد). این کار جریان صحیح ناوبری با کیبورد را تضمین میکند.
مثال پیادهسازی ARIA:
در اینجا یک مثال ساده از نحوه ساختاردهی یک نمای درختی با ویژگیهای ARIA آورده شده است:
<ul role="tree" aria-label="File System">
<li role="treeitem" aria-expanded="true" aria-selected="false" tabindex="0">
<span>Root Folder</span>
<ul role="group">
<li role="treeitem" aria-expanded="false" aria-selected="false" tabindex="-1">
<span>Folder 1</span>
<ul role="group">
<li role="treeitem" aria-selected="false" tabindex="-1"><span>File 1.txt</span></li>
<li role="treeitem" aria-selected="false" tabindex="-1"><span>File 2.txt</span></li>
</ul>
</li>
<li role="treeitem" aria-selected="false" tabindex="-1"><span>Folder 2</span></li>
</ul>
</li>
</ul>
ناوبری با کیبورد
ناوبری با کیبورد برای کاربرانی که نمیتوانند از ماوس استفاده کنند، بسیار مهم است. یک نمای درختی با طراحی خوب باید به طور کامل فقط با استفاده از کیبورد قابل پیمایش باشد. در ادامه، تعاملات استاندارد کیبورد آمده است:
- پیکان بالا (Up Arrow): فوکوس را به گره قبلی در درخت منتقل میکند.
- پیکان پایین (Down Arrow): فوکوس را به گره بعدی در درخت منتقل میکند.
- پیکان چپ (Left Arrow):
- اگر گره باز باشد، آن را میبندد.
- اگر گره بسته باشد یا فرزندی نداشته باشد، فوکوس را به گره والد منتقل میکند.
- پیکان راست (Right Arrow):
- اگر گره بسته باشد، آن را باز میکند.
- اگر گره باز باشد، فوکوس را به اولین فرزند منتقل میکند.
- Home: فوکوس را به اولین گره در درخت منتقل میکند.
- End: فوکوس را به آخرین گره قابل مشاهده در درخت منتقل میکند.
- Spacebar یا Enter: گرهای که فوکوس دارد را انتخاب میکند (اگر انتخاب پشتیبانی شود).
- تایپ کردن (یک حرف یا عدد): فوکوس را به گره بعدی که با کاراکتر تایپ شده شروع میشود، منتقل میکند. جستجو با هر بار فشار دادن کلید ادامه مییابد.
- مثبت (+): گرهای که در حال حاضر فوکوس دارد را باز میکند (معادل پیکان راست در حالت بسته).
- منفی (-): گرهای که در حال حاضر فوکوس دارد را میبندد (معادل پیکان چپ در حالت باز).
- ستاره (*): تمام گرههای سطح فعلی را باز میکند (به طور جهانی پشتیبانی نمیشود اما اغلب مفید است).
پیادهسازی جاوا اسکریپت برای ناوبری با کیبورد:
برای مدیریت رویدادهای کیبورد و بهروزرسانی فوکوس، به جاوا اسکریپت نیاز دارید. در اینجا یک مثال ساده آورده شده است:
const tree = document.querySelector('[role="tree"]');
const treeitems = document.querySelectorAll('[role="treeitem"]');
tree.addEventListener('keydown', (event) => {
const focusedElement = document.activeElement;
let nextElement;
switch (event.key) {
case 'ArrowUp':
event.preventDefault(); // Prevent scrolling the page
// Logic to find the previous treeitem (requires traversing the DOM)
// ...
nextElement = findPreviousTreeitem(focusedElement);
break;
case 'ArrowDown':
event.preventDefault();
// Logic to find the next treeitem
// ...
nextElement = findNextTreeitem(focusedElement);
break;
case 'ArrowLeft':
event.preventDefault();
if (focusedElement.getAttribute('aria-expanded') === 'true') {
// Collapse the node
focusedElement.setAttribute('aria-expanded', 'false');
} else {
// Move focus to the parent
nextElement = findParentTreeitem(focusedElement);
}
break;
case 'ArrowRight':
event.preventDefault();
if (focusedElement.getAttribute('aria-expanded') === 'false') {
// Expand the node
focusedElement.setAttribute('aria-expanded', 'true');
} else {
// Move focus to the first child
nextElement = findFirstChildTreeitem(focusedElement);
}
break;
case 'Home':
event.preventDefault();
nextElement = treeitems[0];
break;
case 'End':
event.preventDefault();
nextElement = treeitems[treeitems.length - 1];
break;
case ' ': // Spacebar
case 'Enter':
event.preventDefault();
// Logic to select the focused node
selectNode(focusedElement);
break;
default:
// Handle character typing for navigating to nodes that start with that character
break;
}
if (nextElement) {
focusedElement.setAttribute('tabindex', '-1');
nextElement.setAttribute('tabindex', '0');
nextElement.focus();
}
});
ملاحظات مهم برای پیادهسازی ناوبری با کیبورد:
- مدیریت فوکوس: همیشه اطمینان حاصل کنید که در هر زمان فقط یک آیتم دارای
tabindex="0"
باشد. هنگام انتقال فوکوس، ویژگیهایtabindex
را به درستی بهروز کنید. - پیمایش DOM: برای پیدا کردن آیتمهای قبلی و بعدی، گرههای والد و گرههای فرزند، DOM را به صورت کارآمد پیمایش کنید. برای سادهسازی این فرآیند، از توابع کمکی استفاده کنید.
- جلوگیری از رویداد: از
event.preventDefault()
برای جلوگیری از انجام اقدامات پیشفرض مرورگر (مانند اسکرول کردن) هنگام کار با کلیدهای جهتنما استفاده کنید. - تایپ کاراکتر: منطقی را برای مدیریت تایپ کاراکتر پیادهسازی کنید تا کاربران بتوانند به سرعت به گرههایی که با یک کاراکتر خاص شروع میشوند، پیمایش کنند. زمان آخرین فشار کلید را ذخیره کنید تا تصمیم بگیرید چه زمانی رشته جستجو باید پاک شود.
طراحی بصری و دسترسیپذیری
طراحی بصری نقش مهمی در کاربردپذیری و دسترسیپذیری نماهای درختی دارد. در اینجا چند دستورالعمل ارائه شده است:
- سلسلهمراتب بصری واضح: از تورفتگی و نشانههای بصری (مانند آیکونهای مختلف برای پوشهها و فایلها) برای نشان دادن واضح سلسلهمراتب درخت استفاده کنید.
- کنتراست رنگ کافی: از کنتراست رنگ کافی بین متن و پسزمینه و بین عناصر مختلف نمای درختی اطمینان حاصل کنید. از ابزارهایی مانند WebAIM Contrast Checker برای تأیید نسبتهای کنتراست استفاده کنید.
- نشانه فوکوس: یک نشانه فوکوس واضح و قابل مشاهده برای آیتمی که در حال حاضر فوکوس دارد، فراهم کنید. این برای کاربران کیبورد ضروری است. تنها به رنگ اکتفا نکنید؛ از یک حاشیه، خط دور یا تغییر پسزمینه استفاده کنید.
- نشانگرهای باز/بسته شدن: از آیکونهای واضح و قابل فهم برای نشانگرهای باز/بسته شدن (مانند علامتهای مثبت/منفی، پیکانها) استفاده کنید. اطمینان حاصل کنید که این آیکونها کنتراست کافی داشته و به اندازه کافی بزرگ باشند تا به راحتی قابل کلیک باشند.
- از استفاده از رنگ به تنهایی برای انتقال اطلاعات خودداری کنید: تنها به رنگ برای نشان دادن وضعیت یک آیتم (مثلاً انتخاب شده، باز شده، خطا) تکیه نکنید. نشانههای بصری جایگزین مانند برچسبهای متنی یا آیکونها را فراهم کنید.
ملاحظات مربوط به صفحهخوانها
کاربران صفحهخوان برای درک و تعامل با نماهای درختی به ویژگیهای ARIA و ناوبری با کیبورد متکی هستند. در اینجا چند ملاحظه کلیدی برای دسترسیپذیری صفحهخوان آورده شده است:
- برچسبهای توصیفی: از
aria-label
یاaria-labelledby
برای ارائه برچسبهای توصیفی برای درخت و آیتمهای جداگانه استفاده کنید. این برچسبها باید مختصر و آموزنده باشند. - اعلام وضعیتها: اطمینان حاصل کنید که تغییرات وضعیت (مانند باز/بسته کردن یک گره، انتخاب یک گره) به درستی توسط صفحهخوان اعلام میشود. این کار با بهروزرسانی صحیح ویژگیهای
aria-expanded
وaria-selected
انجام میشود. - اعلام سلسلهمراتب: صفحهخوانها باید سطح هر گره در سلسلهمراتب را اعلام کنند (مثلاً «سطح ۲، پوشه ۱»). این کار به طور خودکار توسط اکثر صفحهخوانها هنگام پیادهسازی صحیح نقشهای ARIA انجام میشود.
- سازگاری ناوبری با کیبورد: اطمینان حاصل کنید که ناوبری با کیبورد در مرورگرها و صفحهخوانهای مختلف سازگار و قابل پیشبینی است. نمای درختی خود را با چندین صفحهخوان (مانند NVDA، JAWS، VoiceOver) آزمایش کنید تا هرگونه ناهماهنگی را شناسایی و برطرف کنید.
- ارتقای تدریجی (Progressive Enhancement): اگر جاوا اسکریپت غیرفعال باشد، نمای درختی باید همچنان قابل دسترسی باشد، هرچند در حالتی محدودتر. برای ارائه سطح پایهای از دسترسیپذیری حتی بدون جاوا اسکریپت، از HTML معنایی (مانند لیستهای تودرتو) استفاده کنید.
سازگاری بین مرورگرها
دسترسیپذیری باید در مرورگرها و سیستمعاملهای مختلف سازگار باشد. نمای درختی خود را به طور کامل در موارد زیر آزمایش کنید:
- مرورگرهای دسکتاپ: Chrome, Firefox, Safari, Edge
- مرورگرهای موبایل: Chrome (Android and iOS), Safari (iOS)
- سیستمعاملها: Windows, macOS, Linux, Android, iOS
- صفحهخوانها: NVDA (Windows), JAWS (Windows), VoiceOver (macOS and iOS)
از ابزارهای توسعهدهنده مرورگر برای بازرسی ویژگیهای ARIA و رفتار کیبورد استفاده کنید. به هرگونه ناهماهنگی یا مشکلات رندرینگ توجه کنید.
آزمایش و اعتبارسنجی
آزمایش منظم برای اطمینان از دسترسیپذیری نمای درختی شما ضروری است. در اینجا چند روش آزمایش آورده شده است:
- آزمایش دستی: از یک صفحهخوان و کیبورد برای پیمایش نمای درختی استفاده کنید و تأیید کنید که همه ویژگیها قابل دسترسی هستند.
- آزمایش خودکار: از ابزارهای تست دسترسیپذیری (مانند axe DevTools, WAVE) برای شناسایی مشکلات احتمالی دسترسیپذیری استفاده کنید.
- آزمایش کاربر: کاربران با معلولیت را در فرآیند آزمایش مشارکت دهید تا بازخورد واقعی در مورد دسترسیپذیری نمای درختی خود دریافت کنید.
- انطباق با WCAG: هدف خود را برآورده کردن دستورالعملهای دسترسی به محتوای وب (WCAG) 2.1 سطح AA قرار دهید. WCAG مجموعهای از دستورالعملهای شناخته شده بینالمللی برای دسترسیپذیرتر کردن محتوای وب ارائه میدهد.
بهترین شیوهها برای نماهای درختی دسترسپذیر
در اینجا برخی از بهترین شیوهها برای دنبال کردن هنگام طراحی و پیادهسازی نماهای درختی دسترسپذیر آورده شده است:
- با HTML معنایی شروع کنید: از عناصر HTML معنایی (مانند
<ul>
,<li>
) برای ایجاد ساختار پایه نمای درختی استفاده کنید. - نقشها و ویژگیهای ARIA را اعمال کنید: از نقشها و ویژگیهای ARIA برای افزودن معنای مفهومی و ارائه اطلاعات به فناوریهای کمکی استفاده کنید.
- ناوبری قوی با کیبورد را پیادهسازی کنید: اطمینان حاصل کنید که نمای درختی به طور کامل فقط با استفاده از کیبورد قابل پیمایش است.
- نشانههای بصری واضح ارائه دهید: از طراحی بصری برای نشان دادن واضح سلسلهمراتب، وضعیت و فوکوس نمای درختی استفاده کنید.
- با صفحهخوانها آزمایش کنید: نمای درختی را با چندین صفحهخوان آزمایش کنید تا تأیید کنید که برای کاربران صفحهخوان قابل دسترسی است.
- انطباق با WCAG را تأیید کنید: نمای درختی را در برابر دستورالعملهای WCAG تأیید کنید تا اطمینان حاصل کنید که استانداردهای دسترسیپذیری را برآورده میکند.
- کد خود را مستند کنید: کد خود را به وضوح مستند کنید و هدف هر ویژگی ARIA و کنترلکننده رویداد کیبورد را توضیح دهید.
- از یک کتابخانه یا فریمورک استفاده کنید (با احتیاط): استفاده از یک مؤلفه نمای درختی از پیش ساخته شده از یک کتابخانه یا فریمورک معتبر UI را در نظر بگیرید. با این حال، ویژگیهای دسترسیپذیری مؤلفه را به دقت بررسی کرده و اطمینان حاصل کنید که نیازهای شما را برآورده میکند. همیشه به طور کامل آزمایش کنید!
ملاحظات پیشرفته
- بارگذاری تدریجی (Lazy Loading): برای درختهای بسیار بزرگ، بارگذاری تدریجی را پیادهسازی کنید تا گرهها فقط در صورت نیاز بارگذاری شوند. این کار میتواند عملکرد را بهبود بخشد و زمان بارگذاری اولیه را کاهش دهد. اطمینان حاصل کنید که بارگذاری تدریجی به شیوهای دسترسپذیر پیادهسازی شده و بازخورد مناسبی به کاربر هنگام بارگذاری گرهها ارائه میدهد. از نواحی زنده ARIA (ARIA live regions) برای اعلام وضعیت بارگذاری استفاده کنید.
- کشیدن و رها کردن (Drag and Drop): اگر نمای درختی شما از قابلیت کشیدن و رها کردن پشتیبانی میکند، اطمینان حاصل کنید که برای کاربران کیبورد و کاربران صفحهخوان نیز قابل دسترسی است. دستورات کیبورد جایگزین برای کشیدن و رها کردن گرهها فراهم کنید.
- منوهای زمینه (Context Menus): اگر نمای درختی شما شامل منوهای زمینه است، اطمینان حاصل کنید که برای کاربران کیبورد و کاربران صفحهخوان قابل دسترسی هستند. از ویژگیهای ARIA برای شناسایی منوی زمینه و گزینههای آن استفاده کنید.
- جهانیسازی و محلیسازی: نمای درختی خود را طوری طراحی کنید که به راحتی برای زبانها و فرهنگهای مختلف محلیسازی شود. تأثیر جهتهای مختلف متن (مانند راست به چپ) را بر روی طرحبندی بصری و ناوبری با کیبورد در نظر بگیرید.
نتیجهگیری
ایجاد نماهای درختی دسترسپذیر نیازمند برنامهریزی و پیادهسازی دقیق است. با پیروی از دستورالعملهای ذکر شده در این مقاله، میتوانید اطمینان حاصل کنید که نماهای درختی شما برای همه کاربران، از جمله افراد با معلولیت، قابل استفاده و دسترسپذیر هستند. به یاد داشته باشید که دسترسیپذیری فقط یک الزام فنی نیست؛ بلکه یک اصل اساسی در طراحی فراگیر است.
با اولویت دادن به دسترسیپذیری، میتوانید تجربه کاربری بهتری برای همه، صرفنظر از تواناییهایشان، ایجاد کنید. آزمایش و اعتبارسنجی منظم کد شما مهم است. با آخرین استانداردها و بهترین شیوههای دسترسیپذیری بهروز بمانید تا رابطهای کاربری واقعاً فراگیر ایجاد کنید.