Content Description — ویژگی دسترسیپذیری است که توصیف متنی محتوای غیرمتنی را به فناوریهای کمکی منتقل میکند. در iOS این ویژگی accessibilityHint برای UIView است، در Android — contentDescription در نشانگذاری XML. به گزارش W3C WCAG 2.2, 2023، نبود جایگزینهای متنی برای محتوای غیرمتنی یکی از رایجترین نقضهای دسترسیپذیری در برنامههای موبایل است. توصیفهای بهدرست پر شده برنامه را برای افراد با مشکلات بینایی که از VoiceOver و TalkBack استفاده میکنند قابل دسترس میسازد.
نکات کلیدی
Content Description — یک ویژگی رشتهای عنصر رابط است که نمایش متنی محتوای دیداری را به فناوریهای کمکی منتقل میکند. Screen reader (VoiceOver در iOS، TalkBack در Android) به جای تلاش برای شناسایی دیداری عنصر، توصیف را میخواند. توصیف برای تصاویر بدون لایه متنی، آیکونها، نمودارها، کنترلهای سفارشی و هر عنصر غیرمتنی اعمال میشود.
به گزارش Google Material Design, 2024، عناصر بدون contentDescription قاعده WCAG 1.1.1 (محتوای غیرمتنی) را نقض میکنند. بررسی Accessibility Scanner نشان میدهد که تا 40% آیکونها در برنامههای فروشگاهی توصیفی ندارند. کاربر VoiceOver بدون دقیقسازی فقط «تصویر» یا «دکمه» میشنود — چنین رابطی برای پیمایش غیرقابل استفاده میشود.
Content Description جایگزین نمیشود متن قابل مشاهده عنصر. اگر دکمه حاوی برچسب متنی «ارسال» است، نیازی به توصیف اضافه نیست — screen reader متن را میخواند. برای تصاویر، آیکونها و فیلدهای ورودی، توصیف اجباری است.
ابزارهای Accessibility Scanner (Android) و Xcode Accessibility Inspector (iOS) به طور خودکار وجود توصیفها را بررسی میکنند. توصیه میشود این بررسیها را در هر صفحه قبل از انتشار انجام دهید.
کاربر با مشکل بینایی برای درک رابط به VoiceOver اعتماد میکند. اگر آیکون سبد خرید توصیفی نداشته باشد، فقط «دکمه» میشنود. برای اینکه بفهمد دکمه چه کاری میکند، مجبور است آن را کورکورانه فشار دهد — خطر عمل غیرقابل بازگشت. توصیف «حذف محصول از سبد خرید» این مشکل را طی یک ثانیه حل میکند.
کاربر با محدودیتهای موقتی (آفتاب شدید در خیابان، صفحه شکسته) نیز از VoiceOver استفاده میکند. به گزارش Apple Accessibility Report, 2023، حدود 20% از کاربران VoiceOver مشکلات بینایی پایدار ندارند — آنها این قابلیت را بهصورت موقعیتی فعال میکنند.
معیار WCAG 1.1.1 (سطح A) ایجاب میکند که هر محتوای غیرمتنی باید یک جایگزین متنی داشته باشد. استثنا: محتوایی که تزئینی است، فقط برای طراحی دیداری استفاده میشود یا اطلاعاتی را منتقل نمیکند. آزمون تزئینی بودن: اگر عنصر را حذف کنیم، آیا معنای صفحه تغییر میکند؟ اگر نه — میتوان آن را از screen reader پنهان کرد.
Accessibility Label (accessibilityLabel در iOS) — نام عنصری است که screen reader در هنگام فوکوس آن را تلفظ میکند. Content Description (accessibilityHint در iOS) — توضیحات اضافی است که پس از نام بازگو شده و نتیجه عمل را گزارش میدهد.
تفاوت در نمونه دکمه «سبد خرید» به خوبی قابل مشاهده است. Label: «سبد خرید». Description: «صفحه ثبت سفارش را باز میکند». VoiceOver میگوید: «سبد خرید. صفحه ثبت سفارش را باز میکند». اگر فقط Label تنظیم شود، کاربر نمیداند پس از فشار چه میشود.
| ویژگی | iOS | Android | کاربرد |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | نام عنصر (دکمه، فیلد، تصویر) |
| Description | accessibilityHint | contentDescription (گسترده) | توضیح عمل یا معنا |
| Trait | accessibilityTraits | role / className | نقش عنصر (دکمه، عنوان) |
قاعده: Label به سوال «این چیست؟» پاسخ میدهد، Description — «چه میشود؟». در Android، contentDescription میتواند هر دو نقش را ایفا کند، اما در عمل ترجیح است آنها را جدا کنید: از پیوستن «[نام]، [توضیح]» استفاده کنید.
برای حرکات پیچیده (کشیدن برای حذف، فشار طولانی برای منوی موقعیتی) accessibilityHint اجباری است. کاربر VoiceOver از حرکات پنهان اطلاعی ندارد اگر توصیف نشده باشند. در hint عنصر قید کنید: «برای حذف به چپ بکشید».
در پلتفرم iOS، accessibilityHint از طریق ویژگی همنام UIView یا NSObject تنظیم میشود. مقدار — رشته تا 80 کاراکتر. VoiceOver hint را بعد از label در صورتی که حالت توضیحات جزئیات فعال باشد (در تنظیمات VoiceOver — «Verbosity») میخواند.
نمونه تنظیم hint برای دکمه سفارشی:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "افزودن به علاقهمندیها"
self.accessibilityHint = "محصول را در لیست علاقهمندیها ذخیره میکند"
}
}
برای UIImageView بدون محتوای متنی، تنظیم isAccessibilityElement = true و accessibilityHint اجباری است:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "نقره فروش سه ماه گذشته"
VoiceOver میخواند: «نمودار فروش سه ماه گذشته». اگر hint خالی باشد — فقط «تصویر». Apple HIG, 2024 توصیه میکند از افعالی مانند «فشار دهید» یا «لمس کنید» در hint استفاده نکنید — VoiceOver به طور خودکار دستور حرکت را اضافه میکند.
در SwiftUI، hint از طریق تغییردهنده chain تنظیم میشود:
Image(systemName: "trash")
.accessibilityLabel("حذف")
.accessibilityHint("عنصر انتخاب شده را بهطور قطعی حذف میکند")
SwiftUI به طور خودکار تغییردهندهها را برای viewهای مرکب ترکیب میکند. اگر Image داخل Button قرار داشته باشد، SwiftUI از label دکمه به عنوان accessibilityLabel اصلی استفاده میکند.
در Android، contentDescription یا در نشانگذاری XML یا بهصورت برنامهای از طریق setContentDescription() تنظیم میشود. TalkBack در هنگام فوکوس بر عنصر توصیف را بازگو میکند.
نمونه در XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="جستجوی محصولات" />
تنظیم برنامهای برای عناصر پویا:
binding.iconSearch.contentDescription =
"جستجو. صفحه جستجو را با فیلترها باز میکند"
برای تصاویر تزئینی (جداسازندهها، زمینهها، آیکونهای تزئینی) contentDescription = "@null" یا setContentDescription(null) تنظیم کنید — TalkBack چنین عنصری را نادیده میگیرد. در XML: android:contentDescription="@null". رشته خالی "" کار نمیکند — TalkBack همچنان «تصویر» را بازگو میکند.
برای ImageButton همیشه contentDescription تنظیم کنید — TalkBack متن روی تصویر را نمیبیند. برای CheckBox، توصیف باید به طور پویا تغییر کند: «انتخاب شده» / «انتخاب نشده» به جای توصیف استاتیک. از setContentDescription در شنونده وضعیت استفاده کنید.
اطلاعرسانی — توصیف باید معنا را منتقل کند، نه ظاهر را. نه «آیکون آبی با تیک»، بلکه «محصول به سبد خرید اضافه شد». Screen reader به رنگها علاقهای ندارد — به نتیجه علاقه دارد.
کوتاهی — طول مطلوب 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 نشان داد که طول مطلوب توصیف برای screen reader 3–5 کلمه (تا 50 کاراکتر) است. توصیفهای طولانیتر سرعت پیمایش را 30% کاهش میدهند، زیرا کاربر مجبور است قبل از مرحله بعدی منتظر پایان بازگو بماند.
اضافهگویی — توصیف متن قابل مشاهده را تکرار میکند. اگر دکمه حاوی متن «ارسال» است، accessibilityHint = «دکمه ارسال» را تنظیم نکنید. VoiceOver متن را خودکار میخواند و hint صدای زائد اضافه میکند.
اشتباه با Label — استفاده از contentDescription به جای label برای دکمههای متنی. در iOS، accessibilityLabel باید با متن دکمه یکسان باشد (یا اگر متن قابل مشاهده است خالی باشد)، و hint فقط عمل را توضیح میدهد. به گزارش Google Testing Blog, 2024، 23% از برنامههای بررسی شده در Play Store توصیفهای تکراری دارند.
نادیده گرفتن پویایی — توصیف در زمان تغییر وضعیت بهروز نمیشود. به عنوان مثال، توصیف کلید «وایفای» حتی پس از روشن شدن هم «روشن کردن وایفای» باقی میماند. راه درست: به طور پویا توصیف را به «خاموش کردن وایفای» از طریق نظارت بر وضعیت تغییر دهید.
پس از بهروزرسانی طراحی (تغییر آیکونها، جابجایی عناصر)، Content Description اغلب گم میشود. دلیل: طراح تصویر را تغییر میدهد، توسعهدهنده ویژگیهای دسترسیپذیری دارایی جدید را بررسی نمیکند. راه حل: بررسی دسترسیپذیری را به یک مرحله اجباری در code review تبدیل کنید — چکلیستی با بند «Content Description بهروز شد؟» اضافه کنید.
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
سوالات متداول
کاربر VoiceOver یا TalkBack بدون ذکر مقصود فقط «تصویر» یا «دکمه» میشنود. این موجب نقض WCAG 1.1.1 شده و برنامه را برای افراد با مشکلات بینایی غیرقابل دسترس میکند.
خیر. اگر دکمه حاوی برچسب متنی است، VoiceOver آن را خودکار میخواند. این توصیف (accessibilityHint) را میتوان برای توضیح نتیجه فشار اضافه کرد، اما Label مورد نیاز نیست.
در iOS مقدار isAccessibilityElement = false را تنظیم کنید. در Android مقدار contentDescription = "@null" را تنظیم کنید. Screen reader چنین عنصری را کاملاً نادیده میگیرد و صدا تولید نمیکند.
در iOS از NSLocalizedString برای accessibilityHint استفاده کنید، در Android — منابع رشتهای از طریق @string/. ترجمه توصیفها برای تمام زبانهای پشتیبانی شده اجباری است.
آزمونهای UI را اضافه کنید که وجود توصیف را برای تمام ImageView بررسی کنند. در iOS — XCUIApplication، در Android — AccessibilityCheckRule از Espresso. Accessibility Scanner را میتوان از طریق خط فرمان در CI اجرا کرد.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید