إزاي تبني واجهات مستخدم للجميع؟ دليل الـ Accessibility في React
يا هلا بيك يا بشمهندس! فكرت في مرة وأنت قاعد بتكتب كود تفاعل مستخدم (User Interaction) وتعمل مكونات (Components) شكلها مبهر في رياكت (React)، لو التطبيق بتاعك ده هينفع يفتحه شخص كفيف أو عنده مشكلة في النظر أو الحركة؟ للأسف، كتير مننا كمطورين بنهتم بالشكل الجمالي والشاشات بتشتغل إزاي بالماوس، وبننسى خالص إن الويب ده اتعمل عشان يكون متاح للكل (Web for Everyone).
موضوع إمكانية الوصول أو الـ (Web Accessibility) والمعروفة اختصاراً بـ (a11y)، مش رفاهية ولا ميزة إضافية بنحطها في آخر المشروع، دي حاجة أساسية وممكن تكون قانونية كمان في بعض الدول. في المقال ده، هناخد رحلة عملية وسهلة بالعامية المصرية عشان نفهم إزاي نخلي تطبيقات رياكت (React Applications) بتاعتنا ידידותية ومتاحة لكل المستخدمين باستخدام خصائص (ARIA Attributes) وإدارة التركيز (Focus Management).
Table of contents [Show]
- 1 يعني ايه Web Accessibility وليه مهمة في React؟
- 2 الـ Semantic HTML: خط الدفاع الأول في الـ a11y
- 3 قوة الـ ARIA Attributes (Accessible Rich Internet Applications)
- 4 إدارة الـ Focus (Focus Management): السر الحقيقي لتجربة مستخدم ممتازة
- 5 أدوات فحص الـ Accessibility في مشاريع React
- 6 خاتمة: نصيحة من أخ
يعني ايه Web Accessibility وليه مهمة في React؟
باختصار شديد، الـ (Accessibility) هي إننا نخلي المواقع والتطبيقات بتاعتنا قابلة للاستخدام بواسطة الأشخاص ذوي الإعاقة (Disabilities). في عالم الويب، ده معناه إن الشاشة مش بس بتتقري بالعين وبالماوس (Mouse)، لأ دي كمان بتتقري بحاجات زي قارئات الشاشة (Screen Readers) أو بتتحكم فيها عن طريق لوحة المفاتيح بس (Keyboard Navigation).
لما بنشتغل بـ رياكت (React)، إحنا بنبني واجهات ديناميكية (Dynamic Interfaces) عن طريق الـ (Components). المشكلة إن المكونات دي أحياناً بتفقد الدلالة الدلالية (Semantic HTML) بتاعتها، وبتتحول لمجرد عناصر (Divs) و (Spans) ملهاش أي معنى لقارئ الشاشة. وهنا بيجي دورنا عشان نصلح القصة دي.
الـ Semantic HTML: خط الدفاع الأول في الـ a11y
قبل ما ندخل في التعقيد وخصائص الـ ARIA، القاعدة الذهبية بتقول: استعمل دايماً عناصر HTML الصح في المكان الصح. متستعملش (Div) وتعملها كأنها زرار، ما دام تقدر تستعمل عنصر (Button) الحقيقي.
لو بصينا على الكود ده، هنلاقيه غلط جداً من ناحية الـ (Accessibility):
// كود سيء وغير متاح
function BadButton() {
return (
<div onClick={() => alert('Clicked!')}>
اضغط هنا
</div>
);
}
ليه الكود ده سيء؟ لأن الـ (Div) ده مش بياخد فوكاس من لوحة المفاتيح (Keyboard Focus)، وقارئ الشاشة مش هيقراه على إنه زرار. التصحيح بتاعه بالسحر البسيط بتاع الـ HTML هو كده:
// كود صح ومتاح
function GoodButton() {
return (
<button onClick={() => alert('Clicked!')}>
اضغط هنا
</button>
);
}
قوة الـ ARIA Attributes (Accessible Rich Internet Applications)
أحياناً بنضطر نعمل مكونات معقدة زي (Modals) أو (Dropdowns) أو (Tabs)، وهنا عناصر الـ HTML العادية مش بتكفي لوحدها. في الحالة دي بنحتاج نستعين بـ خصائص (ARIA) عشان نوصف حالة المكون لقارئ الشاشة.
تعالوا ناخد مثال لزرار بيفتح قائمة منسدلة (Dropdown Menu) في رياكت، وإزاي نستخدم (ARIA):
import { useState } from 'react';
function AccessibleDropdown() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button
aria-haspopup="true"
aria-expanded={isOpen}
onClick={() => setIsOpen(!isOpen)}
>
القائمة المنسدلة
</button>
{isOpen && (
<ul role="menu">
<li role="menuitem">العنصر الأول</li>
<li role="menuitem">العنصر الثاني</li>
</ul>
)}
</div>
);
}
الخصائص زي aria-expanded و aria-haspopup بتعرف مستخدم قارئ الشاشة حالاً هل القائمة دي مفتوحة ولا مقفولة، وده بيخليه فاهم هو واقف فين بالظبط.
إدارة الـ Focus (Focus Management): السر الحقيقي لتجربة مستخدم ممتازة
واحدة من أكبر المشاكل اللي بتواجه المستخدمين اللي بيعتمدوا على لوحة المفاتيح (Keyboard Users) هي الـ (Focus Trap) أو ضياع الـ (Focus) لما نافذة منبثقة (Modal) تفتح وتقفل.
لما الـ (Modal) يفتح، المفروض الـ (Focus) ينتقل جوه النافذة دي تلقائياً، ولما تتقفل، الـ (Focus) يرجّع للزرار اللي فتحه أساساً. في رياكت، بنقدر نعمل ده بسهولة باستخدام الـ (useRef) والـ (useEffect).
import { useEffect, useRef } from 'react';
function Modal({ isOpen, onClose }) {
const closeButtonRef = useRef(null);
useEffect(() => {
if (isOpen && closeButtonRef.current) {
closeButtonRef.current.focus();
}
}, [isOpen]);
if (!isOpen) return null;
return (
<div className="modal-overlay" role="dialog" aria-modal="true">
<div className="modal-content">
<h2>عنوان النافذة</h2>
<p>محتوى النافذة المنبثقة هنا...</p>
<button ref={closeButtonRef} onClick={onClose}>
إغلاق
</button>
</div>
</div>
);
}
أدوات فحص الـ Accessibility في مشاريع React
عشان تتأكد إن شغلك مظلل وصح، مش لازم تستخدم قارئ شاشة كل مرة (رغم إن ده مطلوب كاختبار نهائي)، فيه أدوات ممتازة بتسهل عليك الحياة:
- ESLint Plugin JSX A11y: إضافة ممتازة للـ Linter بتنبهك وأنت بتكتب الكود لو نسيت تحط
altللصورة أو لو استخدمت عنصر غلط. - Lighthouse: أداة مجانية جوه متصفح كروم بتعمل تدقيق (Audit) شامل لتطبيقك وبتديك تقرير عن الـ Accessibility ونسبتها.
- Axe DevTools: إضافة للمتصفح ممتازة جداً بتحدد لك الأخطاء بالظبط وبتديك حلول ليها.
خاتمة: نصيحة من أخ
يا سيدي الفاضل، بناء تطبيقات بـ رياكت (React) مش بس شاشات شكلها جميل وكود نظيف؛ البرمجة الحقيقية بتظهر لما بنهتم بالإنسان اللي قاعد قدام الشاشة وبيستعمل التطبيق بتاعنا بكفة إيده أو بطريقته الخاصة. اعتبر الـ (Accessibility) مش مجرد "Task" بتعملها عشان تخلص من شغلانة، اعتبرها مسؤولية إنسانية وأخلاقية بتخلي الإنترنت مكان أحسن للكل. ابدأ طبق الحاجات دي في مشروعك الجاي خطوة بخطوة، وهتلاقي الفرق بنفسك!