Content Description: ما هو، مبادئه وكيفية تعيينه لإمكانية الوصول

المؤلف: IT Sectr نُشر: 2026-05-15 وقت القراءة: 8 دق

Content Description هي خاصية إمكانية وصول تنقل وصفاً نصياً للمحتوى غير النصي إلى التقنيات المساعدة. في iOS هي السمة accessibilityHint لـ UIView، وفي Android — contentDescription في ترميز XML. وفقاً لمعيار W3C WCAG 2.2، 2023، فإن غياب البدائل النصية للمحتوى غير النصي يُعد أحد أكثر انتهاكات إمكانية الوصول شيوعاً في تطبيقات المحمول. الأوصاف المعبأة بشكل صحيح تجعل التطبيق متاحاً للأشخاص ذوي الإعاقات البصرية الذين يستخدمون VoiceOver و TalkBack.

الخلاصة

  • Content Description هي وصف نصي لعنصر واجهة المستخدم يعلنه قارئ الشاشة بدلاً من العرض المرئي
  • iOS يستخدم accessibilityHint لـ UIView، Android يستخدم contentDescription في ترميز XML
  • يجب أن يكون الوصف موجزاً (2–4 كلمات) ومفيداً وفريداًضمن الشاشة
  • العناصر الزخرفية يجب أن تحصل على وصف فارغ(isAccessibilityElement = false أو contentDescription = "@null")
  • المحتوى الديناميكي يتطلب تحديث الوصفعند تغير حالة العنصر

ما هو Content Description في إمكانية الوصول

Content Description هي خاصية نصية لعنصر واجهة المستخدم توفر تمثيلاً نصياً للمحتوى المرئي للتقنيات المساعدة. يقرأ قارئ الشاشة (VoiceOver في iOS، TalkBack في Android) الوصف بصوت عالٍ بدلاً من محاولة التعرف على العنصر بصرياً. تُطبق الأوصاف على الصور بدون طبقة نصية والأيقونات والرسوم البيانية وعناصر التحكم المخصصة وأي عناصر غير نصية.

وفقاً لـ Google Material Design، 2024، العناصر بدون contentDescription تنتهك WCAG 1.1.1 (Non-text Content). تظهر فحوصات Accessibility Scanner أن ما يصل إلى 40% من الأيقونات في تطبيقات التسوق تفتقر إلى الأوصاف. مستخدم VoiceOver يسمع «صورة» أو «زر» دون تفاصيل — تصبح هذه الواجهة غير قابلة للاستخدام للملاحة.

Content Description لا تحل محلالنص المرئي للعنصر. إذا كان الزر يحتوي على تسمية نصية «إرسال»، فلا حاجة لتعيين وصف إضافي — سيقرأ قارئ الشاشة النص. للصور والأيقونات وحقول الإدخال، الوصف إلزامي.

أداتا Accessibility Scanner (Android) و Xcode Accessibility Inspector (iOS) تتحققان تلقائياً من وجود الأوصاف. يُنصح بتشغيل هذه الفحوصات على كل شاشة قبل الإصدار.

لماذا Content Description مهم: سيناريوهات المستخدم

المستخدم ضعيف البصر يعتمد على VoiceOver لفهم الواجهة. إذا كانت أيقونة سلة التسوق لا تحتوي على وصف، سيسمع فقط «زر». لمعرفة ما يفعله الزر، عليه الضغط عليه بشكل أعمى — مخاطراً باتخاذ إجراء لا رجعة فيه. وصف مثل «إزالة العنصر من السلة» يحل هذه المشكلة في ثانية واحدة.

المستخدم ذو القيود المؤقتة(شمس ساطعة بالخارج، شاشة مكسورة) يستخدم أيضاً VoiceOver. وفقاً لتقرير Apple Accessibility، 2023، حوالي 20% من مستخدمي VoiceOver ليس لديهم إعاقات بصرية دائمة — بل يشغلون الميزة في مواقف معينة.

WCAG 1.1.1: المحتوى غير النصي

معيار WCAG 1.1.1 (المستوى A) يتطلب أن يكون لكل محتوى غير نصي بديل نصي. الاستثناء: المحتوى الزخرفي المستخدم فقط للعرض المرئي أو الذي لا ينقل معلومات. اختبار الزخرفية: إذا أزلت العنصر، هل يتغير معنى الصفحة؟ إذا لم يتغير — يمكن إخفاؤه عن قارئ الشاشة.

الفرق بين Content Description و Label

Accessibility Label(accessibilityLabel في iOS) هو اسم العنصر الذي ينطقه قارئ الشاشة عند التركيز عليه. Content Description (accessibilityHint في iOS) هو توضيح إضافي يُعلن بعد الاسم ويخبر بنتيجة الإجراء.

الفرق واضح في مثال زر «السلة». Label: «سلة». Description: «سيفتح شاشة الدفع». VoiceOver يقول: «سلة. سيفتح شاشة الدفع». إذا تم تعيين Label فقط، لن يعرف المستخدم ماذا سيحدث بعد الضغط.

جدول: Label مقابل Description

الخاصيةiOSAndroidالغرض
LabelaccessibilityLabelcontentDescriptionاسم العنصر (زر، حقل، صورة)
DescriptionaccessibilityHintcontentDescription (موسعة)توضيح الإجراء أو المعنى
TraitaccessibilityTraitsrole / classNameدور العنصر (زر، عنوان)

القاعدة: Label يجيب عن «ما هذا؟»، Description يجيب عن «ماذا سيحدث؟». في Android، يمكن لـ contentDescription أداء كلا الدورين، لكن من الأفضل عملياً فصلهما: استخدام تسلسل «[الاسم]، [التوضيح]».

متى يكون Description أهم من Label

لـ الإيماءات المعقدة(التمرير للحذف، الضغط المطول للقائمة السياقية)، accessibilityHint إلزامي. مستخدم VoiceOver لا يعرف عن الإيماءات المخفية ما لم تكن موصوفة. حدد: «اسحب لليسار للحذف» في hint العنصر.

iOS: السمة accessibilityHint

في منصة iOS، يتم تعيين accessibilityHint عبر الخاصية التي تحمل الاسم نفسه لـ UIView أو NSObject. القيمة هي سلسلة نصية تصل إلى 80 حرفاً. يقرأ VoiceOver الـ hint بعد الـ label عند تفعيل وضع الأوصاف التفصيلية (في إعدادات VoiceOver — «Verbosity»).

مثال لتعيين hint لزر مخصص:

swift
import UIKit

class CustomButton: UIButton {
    override func awakeFromNib() {
        super.awakeFromNib()
        self.accessibilityLabel = "إضافة إلى المفضلة"
        self.accessibilityHint = "سيحفظ العنصر في قائمة المفضلة"
    }
}

لـ UIImageView بدون محتوى نصي، يجب تعيين isAccessibilityElement = true و accessibilityHint:

swift
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "الرسم البياني للمبيعات للربع الأخير"

VoiceOver يقرأ: «الرسم البياني للمبيعات للربع الأخير». إذا كان الـ hint فارغاً — فقط «صورة». Apple HIG، 2024 يوصي بعدم استخدام أفعال مثل «اضغط» أو «المس» في الـ hints — VoiceOver يضيف تعليمة الإيماءة تلقائياً.

SwiftUI: معدِّل accessibilityHint

في SwiftUI، يُعيّن الـ hint عبر معدِّل تسلسلي:

swift
Image(systemName: "trash")
    .accessibilityLabel("حذف")
    .accessibilityHint("سيحذف العنصر المحدد بشكل دائم")

SwiftUI يجمع تلقائياًالمعدِّلات للعروض المركبة. إذا كانت Image داخل Button، يستخدم SwiftUI تسمية الزر كـ accessibilityLabel أساسي.

Android: الخاصية contentDescription

في Android، تُعيّن contentDescription إما في ترميز XML أو برمجياً عبر setContentDescription(). يعلن TalkBack الوصف عند تركيز العنصر.

مثال في XML:

xml
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_search"
    android:contentDescription="البحث عن المنتجات" />

التعيين البرمجي للعناصر الديناميكية:

kotlin
binding.iconSearch.contentDescription =
    "بحث. سيفتح شاشة البحث مع الفلاتر"

لـ الصور الزخرفية(الفواصل، الخلفيات، الأيقونات الزخرفية) عيِّن contentDescription = "@null" أو setContentDescription(null) — سيتخطى TalkBack هذه العناصر. في XML: android:contentDescription="@null". السلسلة الفارغة "" لا تعمل — سيظل TalkBack يعلن «صورة».

Android: تفاصيل مهمة لـ ImageButton و CheckBox

لـ ImageButton، عيِّن دائماً contentDescription — TalkBack لا يرى النص على الصور. لـ CheckBox، يجب أن يتغير الوصف ديناميكياً: «محدد» / «غير محدد» بدلاً من وصف ثابت. استخدم setContentDescription في مستمع الحالة.

قواعد كتابة الأوصاف

الإفادة — يجب أن ينقل الوصف المعنى، لا المظهر. ليس «أيقونة زرقاء بعلامة صح»، بل «تمت إضافة العنصر إلى السلة». قارئ الشاشة لا يهتم بالألوان — بل يهتم بالنتيجة.

الإيجاز — الطول الأمثل 2–4 كلمات (حتى 80 حرفاً). الأوصاف الطويلة تبطئ الملاحة: VoiceOver يقرأ بتسلسل، كل كلمة هي ثانية من وقت المستخدم. وفقاً لـ Apple WWDC 2023، «Accessibility by Design»، العبارة التي تستغرق أكثر من 5 ثوانٍ للقراءة تقطع التدفق المعرفي.

التفرد — لا يجب أن يكون هناك عنصران على نفس الشاشة بنفس الوصف. لن يتمكن المستخدم من تمييز أي نتيجة سيسببها التركيز على العنصر الأول مقابل الثاني. إذا كان هناك عدة أزرار «اشترِ»، أضف معرفاً: «اشترِ iPhone 15»، «اشترِ iPhone 15 Pro».

التعريب — يجب ترجمة Content Description إلى جميع اللغات التي يدعمها التطبيق. خطأ تعريب الأوصاف هو أحد الأسباب الشائعة لفشل Accessibility Review في App Store.

طول الوصف: أبحاث

أظهر بحث Nielsen Norman Group، 2024 أن الطول الأمثل للوصف لقارئات الشاشة هو 3–5 كلمات (حتى 50 حرفاً). الأوصاف الأطول تقلل سرعة الملاحة بنسبة 30%، حيث يضطر المستخدم لانتظار انتهاء الإعلان قبل الخطوة التالية.

الأخطاء الشائعة عند الاستخدام

التكرار — الوصف يكرر النص المرئي. إذا كان الزر يحتوي على نص «إرسال»، لا تعيّن accessibilityHint = «زر إرسال». سيقرأ VoiceOver النص تلقائياً، وسيضيف الـ hint ضوضاء غير ضرورية.

الخلط مع Label — استخدام contentDescription بدلاً من label للأزرار النصية. في iOS، يجب أن يتطابق accessibilityLabel مع نص الزر (أو يكون فارغاً إذا كان النص مرئياً بالفعل)، ويجب أن يوضح الـ hint الإجراء فقط. وفقاً لمدونة Google Testing، 2024، 23% من التطبيقات التي تمت مراجعتها في Play Store تحتوي على أوصاف مكررة.

تجاهل الديناميكية — لا يتم تحديث الوصف عند تغير الحالة. على سبيل المثال، وصف مفتاح «Wi-Fi» يظل «تشغيل Wi-Fi» حتى بعد تشغيله. النهج الصحيح: تغيير الوصف ديناميكياً إلى «إيقاف Wi-Fi» عبر مراقبة الحالة.

دورات التصيير والانتكاسات

بعد تحديث التصميم (تغيير الأيقونات، إعادة ترتيب العناصر)، غالباً ما يُفقد Content Description. السبب: المصمم يستبدل الصورة ولا يتحقق المطور من خصائص إمكانية الوصول للأصل الجديد. الحل: جعل فحص إمكانية الوصول خطوة إلزامية في مراجعة الكود — أضف عنصر قائمة تحقق: «هل تم تحديث Content Description؟».

كيف تتحقق من Content Description

  • في iOS: Xcode → Accessibility Inspector — اختر العنصر، تحقق من حقلي Label و Hint
  • في Android: ثبّت Accessibility Scannerمن Play Store — شغّله على شاشتك
  • في كلا المنصتين: فعّل VoiceOver/TalkBack وتجول عبر الشاشة بالكامل باستخدام الإيماءات
  • اكتب اختبار واجهة مستخدم يتحقق من contentDescriptionلكل ImageView

مثال اختبار واجهة مستخدم لـ iOS

swift
func testContentDescriptionExists() {
    let app = XCUIApplication()
    app.launch()
    let image = app.images["chart-sales"]
    XCTAssertNotNil(image.label)
    XCTAssertGreaterThan(image.label.count, 0)
}

الأسئلة المتكررة

ماذا يحدث إذا لم أعيّن Content Description لأيقونة؟

سيعلن VoiceOver أو TalkBack ببساطة «صورة» أو «زر» دون تحديد الغرض. هذا ينتهك WCAG 1.1.1 ويجعل التطبيق غير متاح للأشخاص ذوي الإعاقات البصرية.

هل نحتاج Content Description للأزرار النصية؟

لا. إذا كان الزر يحتوي على تسمية نصية، يقرأها VoiceOver تلقائياً. يمكن إضافة وصف (accessibilityHint) لتوضيح نتيجة الضغط، لكن Label غير مطلوب.

كيف أعيّن وصفاً لصورة زخرفية؟

في iOS عيِّن isAccessibilityElement = false. في Android عيِّن contentDescription = "@null". سيتخطى قارئ الشاشة هذه العناصر تماماً دون إصدار صوت.

كيف أعرب Content Description؟

في iOS استخدم NSLocalizedString لـ accessibilityHint، في Android — موارد نصية عبر @string/. ترجمة الأوصاف إلزامية لجميع اللغات المدعومة.

كيف أتحقق من Content Description في CI؟

أضف اختبارات واجهة مستخدم تتحقق من وجود أوصاف لكل ImageView. في iOS — XCUIApplication، في Android — AccessibilityCheckRule من Espresso. يمكن تشغيل Accessibility Scanner في CI عبر سطر الأوامر.

الملخص

  • Content Description هي وصف نصي للمحتوى غير النصي لـ VoiceOver و TalkBack؛ iOS يستخدم accessibilityHint، Android يستخدم contentDescription
  • يجب أن يكون الوصف مفيداً(ينقل المعنى، لا المظهر) وموجزاً (حتى 80 حرفاً)
  • العناصر الزخرفية يجب إخفاؤهاعن قارئات الشاشة عبر isAccessibilityElement = false أو contentDescription = "@null"
  • Label يجيب عن «ما هذا؟» Description يجيب عن «ماذا سيحدث؟»؛ لا تخلط بين هذين الدورين
  • العناصر الديناميكية تتطلب تحديث الوصف عند تغير الحالة (المفاتيح، مربعات الاختيار)
  • تحقق من الأوصاف عبر Accessibility Scanner (Android) و Accessibility Inspector (iOS) قبل كل إصدار
  • عرب Content Description إلى جميع اللغات — خطأ الترجمة يؤدي إلى فشل Accessibility Review

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا