تضمن إمكانية الوصول إلى الويب (a11y) أن تكون مواقع الويب والتطبيقات مناسبة للجميع – بما في ذلك الأشخاص الذين يعانون من إعاقات بصرية وحركية وسمعية وإدراكية. في عام 2026، أصبح WCAG 2.2 هو المعيار العالمي، وقد جعلت الدعاوى القضائية المتعلقة بإمكانية الوصول a11y متطلبًا قانونيًا لمعظم الشركات. يغطي هذا الدليل الأساسيات التي يجب أن يعرفها كل مطور.
📋 Table of Contents
لماذا تعتبر إمكانية الوصول مهمة؟
- 1 مليار شخصفي جميع أنحاء العالم لديهم إعاقة
- المتطلبات القانونيةفي الولايات المتحدة (ADA)، والاتحاد الأوروبي (EAA)، ومعظم البلدان
- فائدة كبار المسئولين الاقتصاديين– الكود الصديق لقارئ الشاشة هو أيضًا صديق لمحركات البحث
- تجربة مستخدم أفضل للجميع– التسميات التوضيحية تساعد في البيئات الصاخبة، والتنقل في لوحة المفاتيح يساعد المستخدمين المتميزين
WCAG 2.2 — المبادئ الأربعة (POUR)
- يمكن إدراكه— يمكن للمستخدمين رؤية/سماع المحتوى (النص البديل، والتسميات التوضيحية)
- قابلة للتشغيل– يمكن للمستخدمين التنقل (لوحة المفاتيح، لا يوجد محتوى يسبب النوبات)
- مفهومة– المحتوى واضح (نص مقروء، رسائل خطأ)
- قوي– يعمل مع التقنيات المساعدة
التقنيات الأساسية
1. HTML الدلالي
<!-- BAD: div soup -->
<div class="header">
<div class="nav">
<div onclick="go('/')">Home</div>
</div>
</div>
<!-- GOOD: semantic HTML -->
<header>
<nav aria-label="Main navigation">
<a href="/">Home</a>
</nav>
</header>
<!-- Use semantic elements for meaning -->
<main> <!-- primary content -->
<article> <!-- self-contained content -->
<section> <!-- thematic grouping -->
<aside> <!-- tangentially related -->
<figure> <!-- image with caption -->
<figcaption> <!-- caption for figure -->
<button> <!-- interactive element (not div!) -->
2. الصور والنص البديل
<!-- Informative image: describe what image conveys -->
<img src="chart.png" alt="Bar chart showing 40% increase in revenue Q1 2026" />
<!-- Decorative image: empty alt (screen readers skip) -->
<img src="divider.svg" alt="" role="presentation" />
<!-- Complex image: describe in text or use longdesc -->
<figure>
<img src="complex-graph.png" alt="Architecture diagram described below" />
<figcaption>
System architecture with three tiers: frontend (React),
API (FastAPI), and database (PostgreSQL).
</figcaption>
</figure>
<!-- Icon with text: hide icon from AT -->
<button>
<svg aria-hidden="true" focusable="false">...</svg>
Download PDF
</button>
<!-- Icon only: add visually hidden label -->
<button aria-label="Close dialog">
<svg aria-hidden="true">...</svg>
</button>
3. التنقل بلوحة المفاتيح
<!-- ALL interactive elements must be keyboard accessible -->
<!-- Use button for actions, a for navigation -->
<button onclick="openModal()">Open</button> <!-- enter/space activates -->
<a href="/about">About</a> <!-- enter activates -->
<!-- Custom interactive element: add tabindex + keyboard handler -->
<div
role="button"
tabindex="0"
onclick="handleClick()"
onkeydown="if(event.key==='Enter'||event.key===' ')handleClick()"
>
Custom Button
</div>
<!-- Skip link: helps keyboard users jump to main content -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>...</header>
<main id="main-content">...</main>
<!-- Never remove focus outline without replacement -->
/* BAD */
:focus { outline: none; }
/* GOOD */
:focus-visible {
outline: 3px solid #0066CC;
outline-offset: 2px;
}
4. ARIA (تطبيقات الإنترنت الغنية التي يمكن الوصول إليها)
<!-- Use ARIA only when HTML semantics aren't enough -->
<!-- aria-label: provides accessible name -->
<button aria-label="Close dialog">✕</button>
<!-- aria-labelledby: references visible text -->
<h2 id="dialog-title">Confirm Delete</h2>
<div role="dialog" aria-labelledby="dialog-title">...</div>
<!-- aria-describedby: provides description -->
<input
id="email"
type="email"
aria-describedby="email-hint"
/>
<p id="email-hint">We'll never share your email.</p>
<!-- aria-live: announce dynamic content changes -->
<div aria-live="polite" aria-atomic="true">
<!-- Screen reader announces when content changes -->
Form submitted successfully!
</div>
<!-- aria-expanded: collapsible elements -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>
<!-- aria-invalid: form validation -->
<input aria-invalid="true" aria-describedby="email-error" />
<p id="email-error" role="alert">Invalid email format</p>
5. اللون والتباين
/* WCAG AA: 4.5:1 for normal text, 3:1 for large text */
/* WCAG AAA: 7:1 for normal text */
/* Check contrast: use WebAIM Contrast Checker */
/* Good contrast */
color: #1a1a1a; /* very dark gray on white: 18.1:1 */
background: #0066CC;
color: white; /* white on blue: 5.4:1 — AA pass */
/* Bad contrast (avoid) */
color: #aaa; /* light gray on white: 2.3:1 — FAIL */
/* Never rely on color alone to convey information */
/* Bad: red text = error, green = success */
/* Good: add icon + text label + color */
.error::before { content: "⚠ Error: "; }
/* Focus indicators must meet contrast requirements too */
:focus-visible {
outline: 3px solid #0066CC; /* sufficient contrast */
}
اختبار إمكانية الوصول
# Automated testing (catches ~30-40% of issues)
npm install --save-dev axe-core @axe-core/playwright
# Run axe in Playwright
import { checkA11y } from 'axe-playwright';
await checkA11y(page, null, { runOnly: ['wcag2a', 'wcag2aa'] });
# Browser extensions
# - axe DevTools (Chrome/Firefox) — most comprehensive
# - Lighthouse (Chrome DevTools) → Accessibility score
# - WAVE (WebAIM) — visual overlay
# Manual testing checklist:
# ☐ Navigate entire page with Tab key only
# ☐ Test with screen reader (NVDA/JAWS Windows, VoiceOver Mac/iOS)
# ☐ Zoom to 200% — does nothing overlap?
# ☐ Turn off CSS — is content readable in order?
# ☐ Check color contrast with DevTools
رد الفعل إمكانية الوصول
// React-specific a11y patterns
// 1. Form labeling
function EmailInput() {
return (
<div>
<label htmlFor="email">Email address</label>
<input id="email" type="email" autoComplete="email" />
</div>
);
}
// 2. Focus management in modals
function Dialog({ isOpen, onClose }: Props) {
const dialogRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (isOpen) dialogRef.current?.focus(); // trap focus
}, [isOpen]);
return isOpen ? (
<div
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
tabIndex={-1}
ref={dialogRef}
>
<h2 id="dialog-title">Confirm Action</h2>
<button onClick={onClose}>Cancel</button>
</div>
) : null;
}
// 3. Live region for dynamic content
function StatusMessage({ message }: { message: string }) {
return (
<div aria-live="polite" aria-atomic="true">
{message}
</div>
);
}
تعد إمكانية الوصول إلى الويب في عام 2026 مطلبًا قانونيًا وميزة تجارية. ابدأ باستخدام HTML الدلالي (80% من a11y يأتي من HTML الصحيح)، وتأكد من إمكانية التنقل في لوحة المفاتيح، وأضف نصًا بديلًا إلى جميع الصور، وحافظ على تباين الألوان. استخدم ax DevTools لإجراء عمليات الفحص التلقائي والاختبار باستخدام VoiceOver/NVDA للتحقق من الصحة في العالم الحقيقي.
🔗 Share this article
✍️ Leave a Comment