٦. مقدمة إلى ARIA (تطبيقات الإنترنت الغنية سهلة الوصول)
نظريأ. ما هو الغرض من WAI-ARIA وكيف يعمل؟
قد يكون جعل "المحتوى الثابت متاحاً" Static content accessible أمراً بسيطاً نسبياً، إلا أن "المحتوى الديناميكي" The dynamic content قد يطرح تحديات أكبر، وهنا يأتي دور معيار WAI-ARIA .
لنلقِ نظرةً على ماهية WAI-ARIA ، والغرض منها، وآلية عملها، وبعض الأمثلة عليها.
يرمز الاختصار WAI-ARIA إلى Web Accessibility Initiative - Accessible Rich Internet Applications "مبادرة إتاحة الويب - تطبيقات الإنترنت الغنية القابلة للإتاحة"، وهي مواصفة تقنية تعزز "إمكانية الوصول" Accessibility إلى "المحتوى الديناميكي" dynamic content ومكونات "واجهة المستخدم" UI (User Interface) .
تجدر الإشارة إلى أن WCAG و WAI-ARIA ليسا متطابقين، إذ توفر معايير WCAG "إرشادات عامة لإتاحة الوصول إلى الويب" General guidelines for web accessibility ، بينما تقدم مواصفات WAI-ARIA "قواعد محددة" Specific Rules لجعل "المحتوى الديناميكي والتفاعلي" Dynamic and interactive content "متاحاً لمستخدمي التقنيات المساعدة" accessible for users of assistive technologies .
إذن، يتمثل الغرض الأساسي من WAI-ARIA في تحسين "إمكانية الوصول" Accessibility إلى "المحتوى الديناميكي" Dynamic content ومكونات "واجهة المستخدم" UI التي لا تتوفر لها نظائر أصلية في لغة "اتش.تي.ام.ال" HTML .
تعمل تقنية WAI-ARIA من خلال تقديم مجموعة من "السمات" Attributes التي يمكنك إضافتها إلى عناصر "اتش.تي.ام.ال" HTML لتوفير "معلومات دلالية إضافية" additional semantic information ، وتُصنَّف هذه "السمات" Attributes إلى "أدوار" (roles) ، و"حالات" (states) ، و"خصائص" (properties).
يُحدِّد دور ARIA الغرض من عنصر ما داخل موقع إلكتروني أو تطبيق ويب. إليك مثال على تعيين "الدور" role ليكون "زرًا" button لعنصر div .
<div role="button">اضغط هنا</div>
من خلال القيام بذلك، فإنك تشير إلى "التقنيات المساعدة" Assistive technology بأن هذا العنصر عبارة عن "زر" Button .
ومع ذلك، فإن "الأدوار" (Roles) لا توفر أي "وظائف" Functionality بحد ذاتها،
فمجرد تعيين "دور" role "زر" button للعنصر div لن يجعله يعمل كزر فعلي.
ولجعله يبدو ويتصرف كزر، ستحتاج إلى استخدام "سي.اس.اس" CSS و "جافاسكريبت" JavaScript لتحقيق النتيجة المطلوبة.
إليك مثال على استخدام HTML و CSS و JavaScript لإنشاء عنصر "زر" button مخصص.
ملاحظة: لا تقلق بشأن محاولة فهم أكواد CSS و JavaScript ، فستتعلم هذه اللغات في وحدات تعليمية قادمة.
index.html
<link href="styles.css" rel="stylesheet">
<div id="custom-btn" role="button">اضغط هنا</div>
<script src="index.js"></script>
styles.css
#custom-btn {
display: inline-block;
padding: 0.4em 1em;
font-size: 1rem;
font-family: sans-serif;
color: buttontext;
background-color: buttonface;
border: 4px solid #ccc;
border-radius: 4px;
cursor: pointer;
user-select: none;
text-align: center;
}
#custom-btn:focus {
outline: 2px solid Highlight;
outline-offset: 2px;
}
#custom-btn:active {
background-color: #ddd;
}
index.js
const button = document.getElementById("custom-btn");
button.addEventListener("click", () => {
alert("تم النقر على الزر!");
});
button.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
button.click();
}
});
معاينة:
من الأفضل دائمًا استخدام "الزر الأصلي" ( Native button ) أو عنصر الإدخال input مع الخاصية type="button" بدلاً من ذلك.
توفر خصائص ARIA تفاصيل إضافية حول العناصر.
على سبيل المثال، تتيح لك الخاصية aria-labelledby "ربط عنصر بتسمية محددة" ( connect an element to a specific label ) :
<h2 id="header-id">نبذة عن HTMLverse</h2>
<button id="button-id" aria-labelledby="header-id button-id">أعرف أكثر</button>
سيجعل هذا العناصر "مفهومة" understandable وقابلة للتصفح لمستخدمي "التقنيات المساعدة" assistive technologies .
لتحقيق أقصى استفادة من WAI-ARIA ، حاول الالتزام باستخدام عناصر "اتش.تي.ام.ال الأصلية" native HTML كلما أمكن ذلك، فهي توفر عادةً مستوى أفضل من "إمكانية الوصول" Accessibility بشكل مباشر ودون الحاجة إلى إعدادات إضافية.
استخدم WAI-ARIA فقط عندما تعجز "عناصر اتش.تي.ام.ال" HTML elements عن تلبية الاحتياجات المطلوبة، ولا تنسَ اختبار عملك باستخدام "التقنيات المساعدة" assistive technologies مثل "قارئات الشاشة" screen readers أو الاستعانة بأشخاص من ذوي "الإعاقة" disabilities لاختباره. كذلك، احرص على تحديث حالات وخصائص WAI-ARIA بالتزامن مع تحديث المحتوى بشكل فوري، وتجنب الإفراط في استخدام ARIA ، إذ قد يؤدي ذلك غالباً إلى حدوث ارتباك.
أسئلة :
ما هو الغرض الأساسي من سمات WAI-ARIA في لغة HTML ؟
١. لتغيير "المظهر المرئي" The visual appearance للعناصر. ❌
٢. لتوفير "معلومات دلالية إضافية" additional semantic information لتحسين "إمكانية الوصول" Accessibility . ✅
٣. لعرض "تلميحات الأدوات" tooltips على العناصر. ❌
٤. لإضافة "تأثيرات حركية" animations للعناصر. ❌
كيف تعمل تقنية WAI-ARIA على تعزيز "إمكانية الوصول إلى الويب" Web Accessibility ؟
١. عن طريق تحسين "سرعة تحميل الصفحة" page load speed . ❌
٢. عن طريق إضافة خصائص توفر "معلومات دلالية إضافية" additional semantic information . ✅
٣. عن طريق "تشفير البيانات" encrypting data . ❌
٤. عن طريق إنشاء "تأثيرات بصرية" visual effects للعناصر. ❌
ماذا تعني عبارة WAI-ARIA ؟
١. مبادرة إتاحة الويب - تطبيقات الإنترنت المتجاوبة والمتقدمة Web Accessibility Initiative - Advanced Responsive Internet Applications . ❌
٢. واجهة إتاحة الويب - تطبيقات الإنترنت ذات الموارد المتاحة Web Accessibility Interface - Accessible Resource Internet Applications . ❌
٣. مبادرة إتاحة الويب - تطبيقات الإنترنت الغنية والمتاحة Web Accessibility Initiative - Accessible Rich Internet Applications . ✅
٤. واجهة تطبيقات الويب - الإتاحة والغنى Web Application Interface - Accessibility and Richness . ❌
ب. ما هي أدوار ARIA ؟
ملاحظة: قد تتضمن بعض هذه الأمثلة التفاعلية أكواد CSS و JavaScript . لا داعي للقلق بشأن محاولة فهم هذه الأكواد، فالغرض من "المعاينات" previews هو المساعدة في توضيح بعض النقاط الرئيسية التي تمت مناقشتها في الدرس.
ARIA اختصار لـ Accessible Rich Internet Applications .
تُحدِّد "أدوار" ARIA roles "الدلالة المعنوية" The semantic meaning لعناصر HTML ، وهي ضرورية لجعل محتوى الويب "متاحاً" Accessible للأشخاص الذين يستخدمون "التقنيات المساعدة" assistive technologies ، مثل "قارئات الشاشة" screen readers .
تتضمن لغة HTML عناصر "دلالية" semantic وعناصر "غير دلالية" non-semantic ، وذلك بناءً على ما إذا كانت تنقل معنىً يتعلق بمحتواها.
تحتوي العديد من عناصر اتش.تي.ام.ال الدلالية ( semantic HTML elements ) بالفعل على "دور" ARIA role مُعيَّن افتراضياً، فعلى سبيل المثال، يمتلك عنصر الزر button دور ARIA role افتراضياً هو button .
<button>زر نموذجي</button>
لكن "العناصر غير الدلالية" ( non-semantic elements ) لا تمتلك "دوراً محدداً" a role ، فعلى سبيل المثال، لن تعرف "قارئات الشاشة" screen readers كيفية تفسير الغرض من عنصر div إذا لم تحدد "دوره" its role بشكل صريح.
<div>
<!-- more elements go here توضع هنا عناصر إضافية -->
</div>
لتحديد "دور إيريا" ARIA role لعنصر ما، ما عليك سوى إضافة السمة role ، على النحو التالي: role="ARIA role" ، حيث تمثل القيمة اسم الدور كما هو محدد في مواصفات ARIA .
إليك مثال على استخدام السمة role بقيمة "alert" :
index.html
<link href="styles.css" rel="stylesheet">
<div class="alert" id="exp-warning" role="alert">
<span class="hidden">ستنتهي صلاحية جلسة تسجيل الدخول الخاصة بك خلال 3 دقائق.</span>
</div>
styles.css
.alert {
background-color: #fff3cd;
border: 1px solid #ffeeba;
color: #856404;
padding: 1em;
margin-top: 1em;
border-radius: 4px;
font-weight: bold;
}
.alert span {
display: inline-block;
}
معاينة:
من المهم ملاحظة أن تحديد "الدور" a role لعنصر ما يؤدي وظيفة واحدة فقط: وهي إعلام "التقنيات المساعدة" assistive technology بالغرض من هذا العنصر، إذ لا يضيف هذا الإجراء أي وظيفة أو سلوك فعلي للعنصر. فإذا كان المستخدمون يتوقعون سلوكاً معيناً مرتبطاً بهذا "الدور" a role ، فإن مسؤولية إضافة ذلك السلوك المتوقع تقع على عاتقك بصفتك "المطور" the developer .
على سبيل المثال، فإن تعيين "دور زر" role="button" لعنصر div لا يجعله قابلاً للنقر بالفأرة أو الاستخدام عبر لوحة المفاتيح تلقائياً،
إذ تقع على عاتق "المطور" the developer مسؤولية إضافة السلوكيات اللازمة التي تتيح لهذا العنصر العمل كـ"زر" button ،
وفي معظم الحالات، يُفضل ببساطة استخدام عنصر button الأصلي.
هناك ست فئات رئيسية لـ ARIA role :
أدوار بنية المستند Document structure roles .
أدوار عناصر الواجهة Widget roles .
أدوار المعالم Landmark roles .
أدوار المناطق الحية Live region roles .
أدوار النوافذ Window roles .
الأدوار التجريدية Abstract roles .
لِنُلقِ نظرةً عليها بمزيدٍ من التفصيل.
تُحدد "أدوار بنية المستند" Document structure roles "الهيكل العام لصفحة الويب" The overall structure of the web page ، فبفضل هذه "الأدوار" roles ، تتمكن "التقنيات المساعدة" assistive technologies من فهم "العلاقات بين الأقسام المختلفة" the relationships between different sections ومساعدة المستخدمين على تصفح المحتوى.
ومع ذلك، فإن معظم "أدوار هيكلة المستندات" The document structure roles لا تُستخدم في "تطوير الويب الحديث" modern web development ، لأن المتصفحات تدعم بالفعل عناصر اتش.تي.ام.ال "الدلالية" Semantic مكافئة، وينبغي إعطاء الأولوية لاستخدام هذه العناصر كلما أمكن ذلك.
عليك تحديد "الأدوار" the roles التي ليس لها عنصر دلالي مكافئ.
على سبيل المثال: شريط الأدوات ( "toolbar" ) ، وتلميح الأداة ( "tooltip" ) ، والخلاصة ( "feed" ) ، والصيغة الرياضية ( "math" ) ، والعرض التقديمي ( "presentation" ) ، و"لا شيء" ( "none" ) ، والملاحظة ( "note" ) .
توجد "أدوار أخرى مماثلة" other similar roles ، ولكن هذه هي الأكثر شيوعاً واستخداماً.
هذا مثال على عنصر div يحمل ARIA role المسمى "math" ،
حيث يحتوي هذا العنصر على "معادلة رياضية" a mathematical equation .
index.html
<link href="styles.css" rel="stylesheet">
<div class="math-expression" role="math" aria-label="س squared + ص squared = 3">
س<sup>2</sup> + ص<sup>2</sup> = 3
</div>
styles.css
.math-expression {
font-family: "Times New Roman", serif;
font-size: 1.2rem;
background-color: #f4f4f4;
border-right: 4px solid #007acc;
padding: 0.75em 1em;
margin-top: 1em;
display: inline-block;
}
.math-expression sup {
font-size: 0.8em;
}
معاينة:
ستلاحظ أيضًا أن عنصر div يحتوي على السمة aria-label . يجب أن تكون قيمة هذه السمة عبارة عن "سلسلة نصية تمثّل التعبير" a string that represents the expression .
تُحدِّد "أدوار عناصر الواجهة" Widget roles الغرض من العناصر التفاعلية ووظيفتها، مثل "أشرطة التمرير" scrollbars .
تتضمن أمثلة "أدوار الأدوات" Widget roles :
شريط التمرير ( "scrollbar" ) ، ومربع البحث ( "searchbox" ) ،
والفاصل"عند التركيز عليه" ( "separator" (when focusable) ) ، شريط التمرير / المنزلق ( "slider" ) ،
وزر التدوير ( "spinbutton" ) ، والمفتاح ( "switch" ) ،
وعلامة التبويب ( "tab" ) ، ولوحة علامات التبويب ( "tabpanel" ) ،
وعنصر الشجرة ( "treeitem" ) .
إليك مثال على "مربع بحث" a searchbox :
index.html
<link href="styles.css" rel="stylesheet">
<div class="search-container" role="search">
<label for="searchbox" class="visually-hidden">بحث</label>
<div
id="searchbox"
class="searchbox"
role="searchbox"
aria-label="ابحث في الموقع"
tabindex="0"
contenteditable="true">
</div>
<button type="button" aria-label="إرسال البحث">بحث</button>
</div>
styles.css
.search-container {
display: flex;
align-items: center;
gap: 0.5em;
margin-top: 1em;
}
.searchbox {
flex: 1;
padding: 0.5em;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1em;
min-height: 1.5em;
}
.searchbox:focus {
border-color: #007acc;
outline: none;
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.3);
}
.button {
padding: 0.5em 1em;
background-color: #007acc;
color: #fff;
border: none;
border-radius: 4px;
cursor:pointer;
}
.button:hover {
background-color: #005fa3;
}
/* Hide visually but keep for screen readers */
/* الإخفاء بصرياً مع الإبقاء عليه متاحاً لقارئات الشاشة */
.visually-hidden {
position: absolute;
background-color: #007acc;
left: 9999px;
}
معاينة:
تحتوي بعض هذه "الأدوار" roles على "عناصر دلالية" Semantic elements مكافئة لها.
وعليك إعطاء الأولوية للعنصر الدلالي على الدور إذا كان ذلك متاحاً،
فعلى سبيل المثال، يُفضل استخدام عنصر "الزر" button في اتش.تي.ام.ال بدلاً من إضافة role="button" إلى عنصر div .
تُستخدم "أدوار المعالم" Landmark roles لتصنيف وتحديد "الأقسام الرئيسية" The primary sections في صفحة الويب،
حيث تعتمد عليها "برمجيات قراءة الشاشة" Screen readers لتوفير وسيلة مريحة للتنقل بين الأقسام الهامة في الصفحة.
ويُستحسن استخدام هذه "الأدوار" Roles باعتدال للحفاظ على "بساطة التخطيط العام" The overall layout simple وسهولة فهمه.
ومن أمثلة "أدوار المعالم" Landmark roles :
"banner" و "complementary" و "contentinfo" و "form" و "main" "navigation" و "region" و "search" .
ولكل دور من هذه الأدوار ما يقابله في لغة اتش.تي.ام.ال،
مثل "العناصر" Elements :
header و footer و aside و form و main و nav و section و search .
لذا، إذا استخدمت عناصر اتش.تي.ام.ال المناسبة لتحديد أقسام الصفحة،
فلن تكون هناك حاجة لإضافة "سمة الدور" role attribute بشكل صريح إلى تلك العناصر.
إليك مثال على "لافتة" a banner :
index.html
<link href="styles.css" rel="stylesheet">
<div class="site-banner" role="banner">
<h1>تصميم ويب مُتاح للجميع</h1>
<nav>
<ul>
<li><a href="#">الرئيسية</a></li>
<li><a href="#">المقالات</a></li>
<li><a href="#">نبذة عنا</a></li>
<li><a href="#">اتصل بنا</a></li>
</ul>
</nav>
</div>
styles.css
.site-banner {
background-color: #007acc;
color: #fff;
padding: 1em 1.5em;
border-radius: 4px;
}
.site-banner h1 {
margin: 0 0 0.5em;
font-size: 1.5em;
}
.site-banner nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
gap: 1em;
}
.site-banner nav a {
color: #fff;
text-decoration: none;
font-weight: 500;
}
.site-banner nav a:hover {
text-decoration: underline;
}
معاينة:
تُحدد "أدوار المنطقة الحية" Live region roles العناصر التي يتغير محتواها ديناميكيًا.
وبهذه الطريقة، تستطيع "برامج قراءة الشاشة" screen readers وغيرها من "التقنيات المساعدة" assistive technologies إبلاغ المستخدمين ذوي "الإعاقة البصرية" visual disabilities بـ"التغييرات" changes .
وتشمل هذه "الأدوار" roles :
"التنبيه" alert ، و"السجل" log ، و"الشريط المتحرك" marquee ، و"الحالة" status ، و"المؤقت" timer .
إليك مثال على "حالة" status :
index.html
<link href="styles.css" rel="stylesheet">
<div class="status-demo">
<button id="update-status-btn">التحقق من الحالة</button>
<div id="status-msg" role="status" class="status-message">
لا توجد تحديثات بعد.
</div>
</div>
<script src="index.js"></script>
styles.css
.status-demo {
margin-top: 1em;
}
button {
padding: 0.5em 1em;
background-color: #007acc;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #005fa3;
}
.status-message {
margin-top: 0.75em;
padding: 0.75em;
background-color: #e8f4ff;
border: 1px solid #b3d8ff;
border-radius: 4px;
font-weight: 500;
}
index.js
const button = document.getElementById("update-status-btn");
const statusMessage = document.getElementById("status-msg");
button.addEventListener("click", () => {
statusMessage.textContent = "اكتمل الرفع بنجاح.";
});
معاينة:
تُحدد "أدوار النافذة" Window roles "النوافذ الفرعية" sub-windows ،
مثل "مربعات الحوار المنبثقة المشروطة" pop-up modal dialogs .
وتشمل هذه الأدوار alertdialog و dialog .
يرجى ملاحظة أنه يُعد الآن من الممارسات الفضلى استخدام عنصر dialog في اتش.تي.ام.ال و"الأساليب" methods المرتبطة به في JavaScript ،
بدلاً من إنشاء "مربع حوار" a dialog يدوياً.
إليك مثال على استخدام "دور حوار" (a dialog role) لـ"حوار مخصص" a custom dialog :
index.html
<link href="styles.css" rel="stylesheet">
<button id="open-dialog">فتح مربع الحوار</button>
<div id="custom-dialog" role="dialog" aria-model="true" aria-labelledby="dialog-title" class="dialog">
<div class="dialog-content">
<h3 id="dialog-title">تأكيد الإجراء</h3>
<p>هل أنت متأكد من أنك تريد حذف هذا الملف؟</p>
<div class="dialog-actions">
<button id="confirm-btn">نعم</button>
<button id="close-dialog">إلغاء</button>
</div>
</div>
</div>
<script src="index.js"></script>
styles.css
body {
font-family: Arial, sans-serif;
margin: 2em;
}
button {
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
background-color: #007acc;
color: white;
font-size: 1em;
}
button:hover {
background-color: #005fa3;
}
.dialog {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
z-index: 500;
}
.dialog-content {
background-color: white;
padding: 1.5em;
border-radius: 8px;
width: 90%;
max-width: 400px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.dialog-actions {
display: flex;
justify-content: flex-end;
gap: 0.5em;
margin-top: 1em;
}
index.js
const dialog = document.getElementById("custom-dialog");
const openBtn = document.getElementById("open-dialog");
const closeBtn = document.getElementById("close-dialog");
const confirmBtn = document.getElementById("confirm-btn");
openBtn.addEventListener("click", () => {
dialog.style.display = "flex";
});
closeBtn.addEventListener("click", () => {
dialog.style.display = "none";
});
confirmBtn.addEventListener("click", () => {
alert("تم حذف الملف.");
dialog.style.display = "none";
});
معاينة:
تأكيد الإجراء
هل أنت متأكد من أنك تريد حذف هذا الملف؟
وأخيراً، لدينا "الأدوار التجريدية" Abstract roles . تساعد هذه "الأدوار" roles في "تنظيم المستند" organize the document ، وهي مخصصة لـ"الاستخدام الداخلي من قِبَل المتصفح فقط" used internally by the browser وليس من قِبَل "المطورين" developers ، لذا ينبغي عليك معرفة وجودها، ولكن لا يجب عليك استخدامها في مواقعك أو تطبيقاتك على الويب.
تتيح لك ARIA roles إنشاء مواقع ويب وتطبيقات ويب "شاملة" inclusive و"متاحة" accessible للجميع ، فهي توفر "معلومات دلالية" Semantic information حول الغرض من عناصر اتش.تي.ام.ال ووظيفتها.
تستخدم "برامج قراءة الشاشة" Screen readers وغيرها من "التقنيات المساعدة" assistive technologies هذه المعلومات لمساعدة المستخدمين على فهم محتوى صفحتك وتكوين "تصور مسبق" expectations حول كيفية استخدامها، مما يساهم في ضمان حصول الجميع على "تجربة مستخدم ممتازة" a great user experience .
أسئلة :
ما هو الغرض الأساسي من ARIA roles ؟
١. لتحديد "المظهر المرئي" the visual appearance للعناصر. ❌
٢. لتحسين "أداء الموقع الإلكتروني" website performance . ❌
٣. لتوفير "معلومات دلالية" semantic information حول الغرض من العناصر. ✅
٤. لتعزيز "التوافق" compatibility مع المتصفحات. ❌
أي فئة من ARIA roles تُستخدم لتحديد الغرض والسلوك الخاص بـ"النوافذ الفرعية" sub-windows ، مثل "مربعات الحوار المنبثقة المشروطة" pop-up modal dialogs ؟
١. أدوار عناصر الواجهة Widget roles . ❌
٢. أدوار بنية المستند Document structure roles . ❌
٣. أدوار المعالم Landmark roles . ❌
٤. أدوار النوافذ Window roles . ✅
أي فئة من ARIA roles تُستخدم للإشارة إلى "المحتوى الديناميكي" dynamic content الذي يجب الإعلان عنه للمستخدمين؟
١. أدوار عناصر الواجهة Widget roles . ❌
٢. أدوار بنية المستند Document structure roles . ❌
٣. أدوار المعالم Landmark roles . ❌
٤. أدوار المناطق الحية Live region roles ✅
ت. ما هي أدوار السمتين aria-label و labelledby ؟
من المهم التأكد من أن جميع المستخدمين، بمن فيهم الأشخاص ذوو "الإعاقة" disabilities ، يمكنهم الوصول إلى المواقع الإلكترونية "دون مشكلات" without issues .
بالنسبة لمستخدمي "قارئات الشاشة" screen readers ، توفر السمتان aria-label و aria-labelledby معلومات بالغة الأهمية حول عناصر الصفحة التي قد تكون "غير واضحة" unclear أو "غير مرئية" invisible .
لنلقِ نظرةً على ماهية السمتين aria-label و aria-labelledby والدور الذي تؤديانه في جعل الويب "متاحاً" accessible للأشخاص ذوي "الإعاقات البصرية" visual impairments وما يتصل بها من إعاقات.
ستلاحظ أن كلاً من aria-label و aria-labelledby يبدآن بالبادئة aria- .
فماذا يعني ذلك؟ يرمز اختصار ARIA إلى "تطبيقات الإنترنت الغنية القابلة للوصول" Accessible Rich Internet Applications ،
وهو عبارة عن مجموعة من السمات التي تبدأ بالبادئة aria- وتتيح للمطورين توضيح الغرض من العناصر لـ"التقنيات المساعدة" assistive technologies .
وتُعد السمة aria-label بمثابة تسمية غير مرئية للعناصر التفاعلية،
إذ تضيف "نصاً تعريفياً" a text label للعنصر يمكن لـ"برامج قراءة الشاشة" screen readers قراءته.
تُعد السمة aria-label مفيدة بشكل خاص للعناصر التي لا تحتوي على نص مرئي ولكنها تتطلب وصفاً لكي تتعرف عليها "قارئات الشاشة" screen readers ،
فعلى سبيل المثال، غالباً ما تحتاج "الأزرار" buttons التي تقتصر على "الأيقونات" icons إلى هذه السمة aria-label لتوضيح الغرض منها.
إليك مثال:
<button arial-label="Search بحث">
<i class"fa-solid fa-magnifying-glass"></i>
</button>
في هذه الحالة، قد يعلن "قارئ الشاشة" screen reader عن هذا "الزر" button بعبارة "زر بحث" ( Search, button ) ،
رغم أن الزر لا يحتوي إلا على "أيقونة" an icon ،
إذ تُعلِم السمة aria-label "قارئات الشاشة" screen readers بالنص الذي يجب استخدامه بدلاً من الأيقونة.
إذا كان "الزر" button يحتوي على النص "بحث" Search بدلاً من "أيقونة" an icon ،
فلن تكون هناك حاجة لاستخدام السمة aria-label ، إذ سيوفر النص "التسمية الخاصة بالزر" The label for the button .
بالنسبة لعناصر "الإدخال" input ، توفر السمة aria-label "تسميةً مباشرةً" a label directly في حال عدم وجود "تسمية مرئية" a visible label مرتبطة بعنصر "الإدخال" input .
تؤدي السمة aria-labelledby الوظيفة ذاتها التي تؤديها السمة aria-label تماماً،
ولكن بدلاً من تحديد النص مباشرةً داخل السمة،
فإنك تستخدم "مرجعاً" a reference لنص موجود بالفعل في الصفحة،
ويجب أن يمتلك هذا النص الموجود سمة id تُستخدم كـ"قيمة مرجعية" The reference value داخل السمة aria-labelledby .
إليك مثال:
<input type="text" aria-labelledby="search-btn">
<button type="button" id="search-btn">بحث</button>
معاينة:
في هذه الحالة، يُستخدم "نص الزر" The text for the button بمثابة "التسمية لحقل إدخال البحث" the label for the search input ،
حيث ستقوم "برمجيات قراءة الشاشة" Screen readers بالإعلان عن الحقل بعبارة مثل "بحث، تعديل" Search, edit .
وإذا قررت لاحقاً تغيير نص الزر إلى "عثور" Find ، فسيتم تحديث تسمية حقل الإدخال تلقائياً لتصبح النص الجديد،
نظراً لأنها تعتمد في "تعريفها" it is referencing على "نص الزر" The button text .
من الممكن أيضاً "دمج" Combining قيم مُعرِّفات IDs متعددة في قيمة واحدة لسمة aria-labelledby . وإليك كيفية عمل ذلك:
<div>
<span id="volume-label">المستوى</span>
<span id="volume-details">اضبط مستوى الصوت</span>
<input
type="range"
min="0"
max="100"
value="30"
aria-labelledby="volume-label volume-details">
</div>
معاينة:
بالنسبة لـ"شريط التمرير" The slider ، سيبحث "قارئ الشاشة" The screen reader عن محتوى عنصري volume-label و volume-details ،
وسيعلن عن (مستوى الصوت) و (ضبط مستوى الصوت).
لقد رأيت أن كلاً من السمتين aria-label و aria-labelledby تساعدان "قارئات الشاشة" screen readers على فهم وظيفة العناصر.
إذن، أيهما ينبغي عليك استخدامه؟ بما أن كلتيهما تؤديان الوظيفة نفسها،
فيمكن استخدام أي منهما، إلا أن هناك بعض المزايا لاستخدام aria-labelledby مقارنةً بـ aria-label :
إذا كان أحدهم يستخدم "خدمة ترجمة" a translation service لترجمة المحتوى الموجود على صفحتك، فقد لا تتم ترجمة النص الوارد في سمة
aria-labelدائمًا.يمكن أن يساعد استخدام السمة
aria-labelledbyأيضاً في منع حدوث "تعارض" mismatch بين "نص التسمية المرئي" the visible label text و"التسمية غير المرئية" the invisible label لمستخدمي "قارئات الشاشة" screen reader ، إذ أن تحديث النص المرئي سيؤدي "تلقائياً" automatically إلى تحديث التسمية غير المرئية.يمكن لسمة
aria-labelledbyأن تسهّل إلى حد كبير "عملية الإنشاء البرمجي" programmatically لتسميات معقدة وغير مرئية تتألف من مصادر نصية متعددة.
ملاحظة أخيرة: لا تستخدم الخاصيتين aria-label و aria-labelledby معاً على العنصر نفسه،
ففي هذه الحالة، سيتم تحديد التسمية غير المرئية (التي تستخدمها قارئات الشاشة) دائماً بواسطة aria-labelledby ،
بينما سيتم تجاهل aria-label تماماً.
أسئلة :
ماذا تعني اختصار ARIA ؟
١. تطبيقات الإنترنت الغنية المُيسَّرة Accessible Rich Internet Applications . ✅
٢. إمكانية الوصول عبر التكامل المتقدم للموارد Advanced Resource Integration Accessibility . ❌
٣. الوصول الآلي إلى تطبيقات الإنترنت الغنية Automated Rich Internet Access . ❌
٤. تطبيقات تفاعلية ومتجاوبة ومُيسَّرة Accessible Responsive Interactive Applications . ❌
ما هي وظيفة كل من aria-label و aria-labelledby ؟
١. تُعدّل هذه الأدوات "المظهر المرئي" the visual appearance للعناصر. ❌
٢. تُضيف تسميات للعناصر لتحسين "إمكانية الوصول" accessibility إليها بواسطة "برامج قراءة الشاشة" screen readers . ✅
٣. تُغيّر هذه الأدوات "وظائف حقول إدخال النماذج" the functionality of form inputs . ❌
٤. تُضيف هذه الأدوات "تأثيرات حركية" animation effects للعناصر. ❌
متى ينبغي استخدام aria-labelledby بدلاً من aria-label ؟
١. عندما تحتاج إلى توفير "تلميح" a tooltip لعنصر ما. ❌
٢. عندما ترغب في تغيير "لون عنصر ما" the color of an element . ❌
٣. عندما تحتاج إلى "إخفاء عنصر" hide an element عن "قارئات الشاشة" screen readers . ❌
٤. عندما يوجد "نص مرئي" visible text على الصفحة يمكن استخدامه كـ"تسمية" a label . ✅
ث. ما هي السمة aria-hidden وكيف تعمل؟
إذا احتجت في أي وقت إلى عرض محتوى مع إخفائه في الوقت نفسه عن مستخدمي "التقنيات المساعدة" assistive technology ،مثل "قارئات الشاشة" screen readers ، فيمكنك استخدام السمة aria-hidden .
ما عليك سوى إضافته إلى عنصر اتش.تي.ام.ال HTML الذي تريد إخفاءه وضبط قيمته على "true" ، كما ترى هنا: aria-hidden="true" .
تُخفي هذه السمة العنصر وجميع "عناصره الفرعية" its children عن "شجرة إمكانية الوصول" The accessibility tree ، مع إبقائها "مرئية" visible على الصفحة. وتشمل حالات الاستخدام الشائعة ما يلي:
"الأيقونات" Icons والصور ذات الغرض "الزخرفي" decorative فقط.
"المحتوى المكرر" Duplicated content .
من المهم تذكر أن السمة aria-hidden تخفي المحتوى فقط عن "التقنيات المساعدة" assistive technology ، مثل "قارئات الشاشة" screen readers .
أما إذا كان ينبغي إخفاء المحتوى عن الجميع، فلا ينبغي استخدام aria-hidden لهذا الغرض.
على سبيل المثال، يجب إخفاء "قائمة الهامبرغر" hamburger menu ،
عندما تكون "مطوية" collapsed عن جميع مستخدمي "لوحة المفاتيح" keyboard users ،
وليس فقط عن مستخدمي "قارئات الشاشة" screen reader ،
وفي هذه الحالة، يمكنك ضبط خاصية "سي.اس.اس" CSS المسماة display على القيمة none لإزالة القائمة من الصفحة المعروضة ومن "شجرة إمكانية الوصول" The accessibility tree أثناء طيها.
لا ينبغي مطلقاً استخدام السمة aria-hidden لإخفاء عنصر "قابل للتركيز عليه" is focusable باستخدام "لوحة المفاتيح" the keyboard ،
فهذه السمة تزيل العنصر من "شجرة إمكانية الوصول" The accessibility tree فقط،
ولا تزيله من "نموذج كائن المستند" DOM .
ونتيجة لذلك، سيظل بإمكان مستخدمي "قارئات الشاشة" screen reader الانتقال إلى العنصر باستخدام "مفتاح طاب" tab،
لكن "قارئ الشاشة" screen reader لن يعلن عن وجوده، مما يجعلهم "يركزون" focus فعلياً على "لاشيء" "nothing" .
إليك مثال نقوم فيه بإخفاء "أيقونة" an icon من "شجرة إمكانية الوصول" The accessibility tree عن طريق إضافة السمة aria-hidden بقيمة "true" .
نُبقي النص متاحاً فقط لـ"التقنيات المساعدة" assistive technologies ، وذلك لتجنب "أي لبس" any confusion قد ينشأ عن "التكرار" the redundancy الناتج عن وجود كل من "الأيقونة" an icon والنص "للغرض نفسه" for the same purpose .
ملاحظة: يتضمن هذا المثال التفاعلي "شبكة توصيل المحتوى" CDN الخاصة بـ Font Awesome ، مما يتيح لك رؤية "أيقونة الترس" The gear icon معروضة في نافذة المعاينة.
<head>
<!-- Font Awesome CDN -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.0/css/all.min.css"
/>
</head>
<button>
<i class="fa-solid fa-gear" aria-hidden="true"><i>
<span class="label">إعدادات<span>
</button>
معاينة:
لا تحتاج إلى استخدام aria-hidden في الحالات التالية:
يحتوي عنصر اتش.تي.ام.ال بالفعل على سمة
hidden."العنصر" The element أو "العنصر السلف له" The element's ancestor مخفي بالفعل باستخدام
display: none."العنصر" The element أو "العنصر السلف له" The element's ancestor مخفي بالفعل باستخدام
visibility: hidden.
في هذه الحالات الثلاث، يكون العنصر "مخفياً" hidden بالفعل عن "شجرة إمكانية الوصول" The accessibility tree ، ولذلك فإن السمة aria-hidden ليست ضرورية.
كما هو الحال عند استخدام أي من سمات ARIA ، ينبغي عليك دائمًا إجراء اختبارات باستخدام "التقنيات المساعدة" assistive technologies — ويفضل أن يتولى أشخاص من ذوي "الإعاقة" disabilities اختبار عملك — للتأكد من سهولة فهمه، حتى مع وجود هذه "العناصر المخفية" hidden elements .
عليك أيضًا أن تدرك أن ضبط السمة aria-hidden على القيمة "false" لن يجعل العنصر مرئيًا لـ"تقنيات المساعدة" assistive technologies إذا كان أي من "العناصر الأب له" its parents يمتلك هذه السمة مضبوطة على القيمة "true" .
تُستخدم السمة aria-hidden لإخفاء العناصر عن الأشخاص الذين يستخدمون "التقنيات المساعدة" assistive technology ، مثل مستخدمي "قارئات الشاشة" screen reader .
على الرغم من أن هذه الطريقة قد تكون مفيدة لإخفاء "العناصر الزخرفية البحتة" purely decorative elements و "المحتوى المكرر" duplicated content ، إلا أنه ينبغي استخدامها باعتدال "لتجنب إعاقة إمكانية الوصول" to avoid hindering accessibility .
بشكل عام، يجب أن يكون "كل المحتوى والوظائف المتاحة" all content and functionality available على الصفحة متاحة أيضاً للأشخاص الذين يستخدمون "التقنيات المساعدة" assistive technology.
إن حالات استخدام السمة aria-hidden محدودة للغاية،
ويجب أن تقتصر في المقام الأول على جعل التجربة أكثر "سلاسة" cleaner لمستخدمي "قارئات الشاشة" screen reader من خلال "إزالة المعلومات الزخرفية البحتة أو المكررة" removing purely decorative or duplicate information .
لا تستخدم aria-hidden لإخفاء محتوى تعتقد أن مستخدمي "قارئات الشاشة" screen reader لن يهتموا به ،
فمن حق هؤلاء المستخدمين الوصول إلى "جميع المعلومات" all information الموجودة على الصفحة.
من خلال اتباع "أفضل الممارسات هذه" these best practices و"اختبار تجربة المستخدم" testing the user experience ، يمكنك إنشاء "تجارب رقمية شاملة للجميع" inclusive online experiences for everyone .
أسئلة :
ما هو الغرض الأساسي من السمة aria-hidden ؟
١. لتحديد "المظهر المرئي" the visual appearance لعنصر ما. ❌
٢. لتحسين "أداء الموقع الإلكتروني" website performance . ❌
٣. لإخفاء العناصر عن "التقنيات المساعدة" assistive technologies . ✅
٤. لتحسين "توافق المتصفحات" browser compatibility . ❌
متى ينبغي استخدام السمة aria-hidden ؟
١. لـ"جميع العناصر" all elements الموجودة في صفحة الويب. ❌
٢. لـ"العناصر المخفية بصرياً" elements that are visually hidden ولكنها تظل مهمة "لتجربة المستخدم" the user experience . ❌
٣. لـ"العناصر الزخرفية" decorative elements التي لا تساهم في "المحتوى الرئيسي" the main content . ✅
٤. للعناصر التي تتم إضافتها أو إزالتها "ديناميكياً" dynamically . ❌
ما هي المخاطر المحتملة للإفراط في استخدام السمة aria-hidden ؟
١. انخفاض "أداء الموقع الإلكتروني" website performance . ❌
٢. "عدم التوافق" Incompatibility مع المتصفحات القديمة. ❌
٣. إعاقة "إمكانية الوصول" accessibility للمستخدمين ذوي "الإعاقة" disabilities . ✅
٤. زيادة "حجم الملف" file size . ❌
ج. ما هي السمة aria-describedby وكيف تعمل؟
تُستخدم السمة aria-describedby لتوفير معلومات إضافية حول عنصر ما لمستخدمي "قارئات الشاشة" screen reader ،
وذلك من خلال الإشارة إلى محتوى موجود بالفعل في الصفحة.
وتُنشئ هذه السمة "رابطاً برمجياً" a programmatic association بين العنصر والمحتوى ( وهو ما يُعرف تقنياً بـ "الوصف المُتاح" أو an accessible description )،
مما يتيح لـ"قارئات الشاشة" screen readers إطلاع المستخدمين على تلك المعلومات الإضافية عند تفاعلهم مع العنصر.
يتمثل الاستخدام الأكثر شيوعاً للسمة aria-describedby في ربط التعليمات ورسائل الخطأ بحقول الإدخال في النماذج.
ونظراً لتعدد الطرق التي يستخدمها مستخدمو "قارئات الشاشة" screen reader للتنقل داخل الصفحة، فقد تفوتهم هذه الرسائل أثناء التنقل بين حقول الإدخال،
لذا فإن استخدام aria-describedby يضمن سماعهم لتلك الرسائل.
لنلقِ نظرةً على بعض الأمثلة لفهم كيفية عمل ذلك. في هذا المثال الأول، لدينا عنصر "نموذج" form يقبل "كلمة مرور" a password .
اكتب "بضعة أحرف" a few characters في "حقل إدخال كلمة المرور" the password input field . ستلاحظ أن "كلمة المرور" the password تظهر مموهة ( "مخفية" masked ) في نافذة المعاينة. كما ستلاحظ أن "النص الإرشادي الخاص بكلمة المرور" the password-help text يظل باللون الأحمر إلى أن تقوم بإدخال 8 أحرف أو أكثر.
ملاحظة: يستخدم هذا المثال التفاعلي لغتي CSS و JavaScript لتحديث لون النص المساعد الخاص بكلمة المرور بشكل "ديناميكي" dynamically .
index.html
<link href="styles.css" rel="stylesheet">
<form>
<label for="password">كلمة المرور:</label>
<input type="password" id="password" aria-describedby="password-help" />
<p id="password-help">يجب أن تتكون كلمة المرور من 8 أحرف على الأقل.</p>
</form>
<script src="index.js"></script>
styles.css
#password-help {
color: red;
}
index.js
const passwordEl = document.getElementById("password");
const passwordHelpText = document.getElementById("password-help");
passwordEl.addEventListener("input", (e) => {
const userInput = e.target.value;
passwordHelpText.style.color = userInput.lenght >= 8 ? "green" : "red";
});
معاينة:
نستخدم عنصر التسمية label لنص "كلمة المرور" Password ونربطه بـ"حقل إدخال كلمة المرور" The password input field .
لدينا أيضاً عنصر "فقرة" paragraph يوضح "متطلبات كلمة المرور" the password requirements .
ونستخدم السمة aria-describedby لربط "حقل إدخال كلمة المرور" The password input field بمتطلبات كلمة المرور الواردة في عنصر "الفقرة" The paragraph .
فعندما يتفاعل مستخدم يعتمد على "قارئ الشاشة" screen reader مع حقل "الإدخال" input هذا،
سيقوم "قارئ الشاشة" screen reader بالإعلان عن اسم الحقل input ( "كلمة المرور" Password )،
وقد يعلن أيضاً عن متطلبات كلمة المرور.
ومع ذلك، لا يُعد هذا "ضماناً مطلقاً" an absolute guarantee ،
إذ قد لا تعلن "بعض برامج قراءة الشاشة" some screen readers عن "المحتوى الإضافي" the additional content تلقائياً،
أو قد تعلن عنه في ظروف محددة فقط. وهذا أمر شائع،
فكل "قارئ شاشة" screen reader يختلف عن الآخر ويتعامل مع سمات ARIA بطريقته الخاصة.
ورغم ذلك، لا يقلل هذا من أهمية استخدام السمة aria-describedby ،
فهي ستظل مفيدة لمستخدمي "برامج قراءة الشاشة" screen reader بشكل عام.
من حالات الاستخدام الجيدة الأخرى لسمة aria-describedby وجود زر للحذف. إليك مثال على "زر حذف" delete button متبوع بـ"رسالة تصف ما سيحدث عند النقر على الزر" a message describing what will happen when the button is clicked :
<button aria-describedby="delete-message">حذف</button>
<p id="delete-message">تحذير! جميع عمليات الحذف نهائية.</p>
معاينة:
تحذير! جميع عمليات الحذف نهائية.
تماماً كما في المثال السابق، "نربط زر الحذف بالرسالة" we associate the delete button with the message باستخدام السمة aria-describedby ،
إذ يجب أن تتطابق قيمة "المعرِّف" id مع قيمة السمة aria-describedby .
تُعد السمة aria-describedby "سمةً قويةً" a powerful attribute يمكن استخدامها لضمان توفير "معلومات إضافية" additional information حول عنصر ما لـ"مستخدمي قارئات الشاشة" screen reader users عند تفاعلهم معه،
إذ تُستخدم غالباً لربط "التعليمات ورسائل الخطأ" instructions and error messages بـ"حقول الإدخال في النماذج" form inputs ،
وذلك للحد من احتمالية تفويت المستخدمين لهذه الرسائل أثناء تنقلهم داخل "النموذج" the form .
أسئلة :
ما هو الغرض من السمة aria-describedby في HTML ؟
١. لتحديد "مُعرّف فريد" a unique identifier لعنصر ما. ❌
٢. لتوفير "معلومات إضافية" additional information حول عنصر ما لـ"تقنيات المساعدة" assistive technologies . ✅
٣. لتحديد "لغة مستند اتش.تي.ام.ال" The language of an HTML document . ❌
٤. للتحكم في ظهور "عنصر اتش.تي.ام.ال" an HTML element. ❌
في الأمثلة المقدمة، كيف تعزز السمة aria-describedby "تجربة المستخدم" the user experience لـ"حقول النماذج" form fields ؟
١. يُغيّر هذا الإجراء "المظهر المرئي" the visual appearance لـ"حقول النموذج" the form fields . ❌
٢. يُضيف "نصًا وصفيًا إضافيًا" additional descriptive text لـ"حقول النموذج" form fields لتوفير سياق أو تعليمات أكثر تفصيلًا. ✅
٣. يتحقق من صحة "قيم الإدخال" input values في "حقول النموذج" form fields . ❌
٤. يملأ "حقول النموذج" form fields تلقائيًا بـ"القيم الافتراضية" default values . ❌
أي مما يلي يمثل الطريقة الصحيحة لاستخدام السمة aria-describedby "داخل نموذج" inside of a form ؟
١.
<form>
<label for="password">كلمة المرور:</label>
<input type="password" id="password" aria-describedby="password-help" />
<p id="password-help">يجب أن تتكون كلمة المرور من 8 أحرف على الأقل.</p>
</form>
٢.
<form>
<label for="password">كلمة المرور:</label>
<input type="password" id="password" aria-describedby="password" />
<p id="password-help">يجب أن تتكون كلمة المرور من 8 أحرف على الأقل.</p>
</form>
٣.
<form>
<label for="password">كلمة المرور:</label>
<input type="password" id="password" aria-describedby="password-help" />
<p>يجب أن تتكون كلمة المرور من 8 أحرف على الأقل.</p>
</form>
٤.
<form>
<label for="password">كلمة المرور:</label>
<input
type="password"
id="password"
aria-describedby="يجب أن تتكون كلمة المرور من 8 أحرف على الأقل."
/>
</form>